📊 WHERE filters rows. HAVING filters groups.
Need customers with 5+ orders? Groups with average > 100? HAVING clause filters aggregated results.
📝 Basic HAVING
-- Customers with 5+ orders
SELECT
customer_id,
COUNT(*) as order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(*) >= 5;
-- Departments with average salary > 50000
SELECT
department,
AVG(salary) as avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
🎯 WHERE vs HAVING
-- WHERE (before GROUP BY)
SELECT
category,
COUNT(*) as product_count
FROM products
WHERE price > 100 -- Filter rows before grouping
GROUP BY category;
-- HAVING (after GROUP BY)
SELECT
category,
COUNT(*) as product_count
FROM products
GROUP BY category
HAVING COUNT(*) > 10; -- Filter groups after aggregation
💡 Use Cases
- Find customers with high order volume
- Identify top-selling products
- Filter categories with enough products
- Find departments with high average salary
- Detect outliers in grouped data
“WHERE didn’t work with COUNT(*). Discovered HAVING. Now can filter aggregated results. Essential for reporting.”
