Reference

HAVING

Filter after aggregation. HAVING sees aggregate results (COUNT(*), SUM(total), AVG(x)) that WHERE cannot, because WHERE runs before GROUP BY, and aggregates don't exist yet at that point.

Syntax #

sql
SELECT key_col, COUNT(*) AS n
FROM table_name
GROUP BY key_col
HAVING COUNT(*) > 1;

Example #

Loading SQL editor...
Info

Filtering a raw column in HAVING works but is slow — that filter belongs in WHERE. WHERE cuts rows before grouping (cheap); HAVING filters after aggregation has already materialized every group. If the predicate doesn't reference an aggregate, move it to WHERE. A query with WHERE status = 'paid' GROUP BY user_id HAVING COUNT(*) >= 2 will outperform the same thing with both filters in HAVING on any non-trivial data volume.