▶ Try SQL

SQL HAVING

Filter groups after aggregation — the WHERE clause for GROUP BY results.

Why HAVING exists

WHERE filters individual rows before grouping. Once groups are formed, WHERE can't filter them because the aggregate values (SUM, COUNT…) don't exist yet. HAVING filters groups after they've been computed.

Basic example

SQL — customers with more than 2 orders
SELECT customer_id, COUNT(*) AS order_count FROM orders GROUP BY customer_id HAVING COUNT(*) > 2 ORDER BY order_count DESC;

WHERE vs HAVING

AspectWHEREHAVING
Runs when?Before GROUP BYAfter GROUP BY
FiltersIndividual rowsGroups (aggregate results)
Can use aggregates?❌ No✅ Yes
Typical useFilter raw dataFilter summarized data

Combining WHERE and HAVING

SQL — UK customers with total spend > 500
SELECT c.name, SUM(o.amount) AS total_spent FROM customers c JOIN orders o ON c.id = o.customer_id WHERE c.country = 'UK' -- 1. Filter rows BEFORE grouping GROUP BY c.name -- 2. Group remaining rows HAVING SUM(o.amount) > 500 -- 3. Filter groups AFTER aggregation ORDER BY total_spent DESC;

More HAVING examples

SQL — products sold in more than 3 cities
SELECT o.product, COUNT(DISTINCT c.city) AS city_count FROM orders o JOIN customers c ON o.customer_id = c.id GROUP BY o.product HAVING COUNT(DISTINCT c.city) > 3;
SQL — find duplicate emails
SELECT email, COUNT(*) AS occurrences FROM customers GROUP BY email HAVING COUNT(*) > 1;
Full execution order FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT. Put it on a sticky note. Interviewers love asking about this.