COUNT is an ANSI-standard aggregate function that scans the rows produced by a query block and returns a single integer. Its behavior depends on the argument supplied: COUNT(*) tallies every row, including those with NULL values; COUNT(expression) skips rows where the evaluated expression is NULL; COUNT(DISTINCT expression) removes duplicate, non-NULL values before counting. If no qualifying rows exist, COUNT returns 0, never NULL. Because it is computed after WHERE filtering but before ORDER BY, the result reflects the exact set of rows fed into the aggregation layer. COUNT is deterministic and can be combined with GROUP BY, HAVING, window functions (COUNT() OVER …), and other aggregates. Performance is typically O(n) on the filtered result set, but many databases optimize COUNT(*) with metadata or index-only scans when no filters are involved. Caveats: COUNT(column) ignores NULLs, which sometimes surprises users expecting a full row count; COUNT(DISTINCT) can be resource-intensive on large, high-cardinality datasets; and COUNT(*) on views with joins may multiply rows unless DISTINCT or GROUP BY is applied.
1. *
(asterisk) - special token - counts all rows including NULLs2. expression
(any numeric, string, or Boolean expression) - rows where expression is NULL are skipped3. DISTINCT
(optional keyword) - removes duplicate non-NULL values before countingSQL-92 standard
COUNT(*) tallies every row that survives the WHERE clause, even if every column value in a row is NULL.
COUNT(column) skips rows where column evaluates to NULL, so tables with missing data often show a difference between the two counts.
Run COUNT(DISTINCT user_id) on the relevant table or subquery. DISTINCT removes duplicate non-NULL user_id values before the count.
Yes. Use HAVING to filter aggregated results: SELECT department_id, COUNT(*) AS cnt FROM employees GROUP BY department_id HAVING COUNT(*) > 10;