Two Filters At Two Stages
Both WHERE and HAVING remove rows, but they act at different points in the pipeline. Mixing them up either causes errors or silently changes your results.
When Each Runs
- WHERE runs before GROUP BY, so it filters individual rows and cannot see aggregates.
- HAVING runs after GROUP BY, so it filters whole groups and can compare aggregate values.
Choosing The Right One
- Use WHERE to drop rows you never want to count, such as cancelled orders.
- Use HAVING to keep only groups that meet an aggregate condition, such as customers with more than ten orders.
- For best performance push as much filtering as possible into WHERE, because removing rows early shrinks the work that grouping must do.
Key idea
WHERE filters rows before grouping and HAVING filters groups after, so put row conditions in WHERE and aggregate conditions in HAVING.