What's the difference between WHERE and HAVING?
3 minbeginnersql-basicswherehavinggroup-by
Quick Answer
`WHERE` filters individual rows *before* grouping/aggregation happens, and cannot reference aggregate functions. `HAVING` filters *groups* after `GROUP BY` has run, and is specifically for conditions on aggregates like `COUNT(*)` or `SUM(x)`. If a query has no `GROUP BY`, `HAVING` treats the whole result set as one group.
Detailed Answer
Both clauses filter rows, but at different stages of query processing (see the logical execution order: FROM → WHERE → GROUP BY → HAVING → SELECT).
WHERE: filters rows before grouping
SELECT department, AVG(salary) AS avg_salary
FROM employees
WHERE hire_date >= '2020-01-01' -- filters individual employee rows first
GROUP BY department;
HAVING: filters groups after aggregation
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 75000; -- filters the resulting department groups
Combining both
SELECT department, COUNT(*) AS headcount
FROM employees
WHERE status = 'active' -- row-level filter first
GROUP BY department
HAVING COUNT(*) >= 10; -- group-level filter second
The rule of thumb
- Use
WHEREfor conditions on raw column values that exist before grouping. - Use
HAVINGfor conditions on the result of an aggregate function. - Trying to put an aggregate condition in
WHERE(WHERE COUNT(*) > 5) fails, becauseCOUNT(*)doesn't exist untilGROUP BYhas executed. - Filtering earlier with
WHEREis almost always more efficient than filtering later withHAVING, becauseWHEREreduces the row set before the (often expensive) grouping and aggregation work happens. Never useHAVINGfor a condition that could be expressed inWHERE.