SQL HAVING Clause Explained: Filter Your Data Like a Pro
The only clause that lets you filter based on an aggregate result.
The HAVING clause exists for one specific reason: WHERE cannot filter based on the result of an aggregate function, because aggregates aren't calculated until after grouping happens. HAVING fills that gap.
Basic Syntax
SELECT column, AGG_FUNCTION(column) FROM table_name GROUP BY column HAVING AGG_FUNCTION(column) condition;
Example: Departments With More Than 5 Employees
SELECT department, COUNT(*) AS employee_count FROM employees GROUP BY department HAVING COUNT(*) > 5;
Example: Products With Average Rating Above 4
SELECT product_id, AVG(rating) AS avg_rating FROM reviews GROUP BY product_id HAVING AVG(rating) > 4;
Combining HAVING with Multiple Conditions
SELECT department, AVG(salary) AS avg_salary, COUNT(*) AS total FROM employees GROUP BY department HAVING AVG(salary) > 50000 AND COUNT(*) > 3;
💡 Tip: A quick way to remember the difference:
WHERE filters rows before grouping, HAVING filters groups after aggregation.Common Mistakes to Avoid
- Using
HAVINGwithout aGROUP BYwhen a simpleWHEREwould do - Referencing a column in
HAVINGthat isn't part ofGROUP BYor an aggregate - Expecting
HAVINGto speed up a query — it filters after the aggregation has already been computed
Once this distinction clicks, HAVING stops feeling like an extra rule to memorize and starts feeling like the obvious tool for the job.