What is the difference between WHERE and HAVING?
Quick Answer
WHERE filters rows before grouping and can't use aggregate functions. HAVING filters groups after GROUP BY and is where aggregate conditions go (HAVING COUNT(*) > 5). Use WHERE to cut rows early (it's faster) and HAVING only for conditions on the aggregated result.
WHERE runs before GROUP BY, so it filters individual rows and can't see aggregates. HAVING runs after grouping, so it filters the groups and that's where conditions like COUNT(*) > 5 or SUM(Total) > 10000 go. The rule I follow is: any filter that doesn't need an aggregate goes in WHERE because it cuts the row count before the expensive grouping, and only genuinely aggregate conditions go in HAVING.
Logical processing order: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY.
WHERE OrderDate >= '2026-01-01'— removes rows before aggregation, so fewer rows to group. Always prefer this for non-aggregate filters.HAVING SUM(Total) > 10000— you can only know the sum after grouping, so this must beHAVING.- Putting a plain column filter in
HAVINGworks but is slower and misleading — keep it inWHERE.
SELECT CustomerId, COUNT(*) AS Orders, SUM(Total) AS Spend
FROM dbo.Orders
WHERE OrderDate >= '2026-01-01' -- filter rows first
GROUP BY CustomerId
HAVING SUM(Total) > 10000; -- then filter groups