WHERE Filters Rows Before Grouping and HAVING Filters Groups After
WHERE is applied to individual rows before they are grouped; HAVING is applied to the groups after the aggregates have been computed. That means a condition that does not depend on an aggregate belongs in WHERE, where it throws rows away before the expensive grouping step, and putting it in HAVING makes the engine group rows it is about to discard. Only conditions on aggregate values, such as HAVING COUNT(*) > 5, genuinely need HAVING.
Questions this Concept answers
- Why does expressing a non-aggregate condition in `WHERE` rather than `HAVING` describe less work?
Grouping Rows with GROUP BY and Filtering Aggregates with HAVING Instead of WHERE in SQL
GROUP BY partitions a result set into groups of rows sharing the same values in the grouping columns, and an aggregate function then produces one value per group, which is why every non-aggregated co…