.jpg)
It's strictly about timing of execution:
WHERE: Filters raw rows before they are grouped.HAVING: Filters aggregated groups after the math is done.<aside> 💡
If you need to filter by a calculated value (like SUM or COUNT), you need HAVING.
</aside>
To understand the difference, we have to look at how the database engine actually processes the query. It doesn't read top-to-bottom; it follows a specific order of operations:
FROM (Find the table)WHERE (Filter raw rows - "Pre-filter")GROUP BY (Bucket the remaining rows)HAVING (Filter the buckets - "Post-filter")SELECT (Return the columns)GROUP BYBefore you can filter groups, you have to make them. GROUP BY collapses multiple rows into a single row based on shared values.
<aside> 💡
Once you group, you lose access to individual row details unless you wrap them in an aggregate function (SUM, AVG, MAX, ARRAY_AGG).
</aside>