So far in SQL, we’ve learned these keywords: FROM JOIN WHERE GROUP BY Now we’re introducing a new keyword: 🔥 HAVING At first, HAVING looks very similar to WHERE. B
MSMuhammad SufiyanSoftware Engineer · 6d ago
Backend Engineering HubT-
So far in SQL, we’ve learned these keywords:
FROM
JOIN
WHERE
GROUP BY
Now we’re introducing a new keyword:
🔥 HAVING
At first, HAVING looks very similar to WHERE.
But there is one very important difference.
🧠 WHERE vs HAVING (Very Important)
Keyword
Filters What?
WHERE
Filters rows
HAVING
Filters groups
This is the most important rule.
🧩 Order of SQL Execution
When writing grouped queries, SQL follows this order:
SELECT
FROM
JOIN
WHERE
GROUP BY
HAVING
Notice something important:
👉 HAVING always comes after GROUP BY.
And here’s another rule:
You will never see HAVING without GROUP BY.
You can use GROUP BY without HAVING.
But if you want to filter groups, you must use HAVING.
🎯 Practical Example
Let’s solve a real problem.
🧠 Goal:
Find the number of comments for each photo
Where:
The photo_id is less than 3
The photo has more than 2 comments
Notice something interesting:
There are two different filters here.
🔎 First Filter: photo_id < 3
This filter checks a condition on individual rows.
That means we use:
WHERE
Because WHERE filters rows.
🔎 Second Filter: Photo has more than 2 comments
This requires:
GROUP BY photo_id
COUNT(*)
Filtering based on COUNT
Since COUNT is an aggregate function, this filter must use:
HAVING
Because HAVING filters groups after aggregation.
🧠 Step-by-Step Mental Model
Imagine our comments table:
id
photo_id
1
1
2
1
3
1
4
2
5
3
6
4
Step 1️⃣ WHERE Phase (Row Filtering)
We apply:
WHERE photo_id < 3
Now we remove rows where photo_id is 3 or 4.
Remaining rows:
id
photo_id
1
1
2
1
3
1
4
2
Step 2️⃣ GROUP BY Phase
We group by photo_id.
Group 1:
3 comments
Group 2:
1 comment
Step 3️⃣ HAVING Phase (Group Filtering)
We apply:
HAVING COUNT(*) > 2
Group 1 → 3 comments ✅ keep
Group 2 → 1 comment ❌ remove
Final result:
photo_id
count
1
3
🧾 Final Query
Here is the complete SQL query:
SELECT photo_id, COUNT(*)
FROM comments
WHERE photo_id < 3
GROUP BY photo_id
HAVING COUNT(*) > 2;
🧠 Why Not Use WHERE Instead of HAVING?
This will NOT work:
WHERE COUNT(*) > 2
Because:
WHERE runs before GROUP BY
COUNT() doesn’t exist yet at that stage
Aggregation happens after grouping.
That’s why HAVING exists.
🏗 Execution Flow (Super Important Concept)
Here’s how PostgreSQL processes it internally:
1. FROM → get table 2. WHERE → filter rows 3. GROUP BY → create groups 4. COUNT/SUM/etc → calculate aggregates 5. HAVING → filter groups 6. SELECT → return final result
🔥 When Do We Use HAVING?
Use HAVING when:
You are using GROUP BY
You want to filter based on an aggregate function
You need conditions like:
COUNT(*) > 5
SUM(amount) > 1000
AVG(score) > 70
🧠 Real-World Business Examples
🛒 Find customers who placed more than 5 orders:
SELECT user_id, COUNT(*)
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 5;
💰 Find products generating more than $10,000 revenue:
SELECT product_id, SUM(price)
FROM sales
GROUP BY product_id
HAVING SUM(price) > 10000;
🎯 Final Summary
WHERE:
Filters individual rows.
GROUP BY:
Creates groups.
HAVING:
Filters groups after aggregation.
🧪 Practice Questions for Students
1. Find departments with more than 10 employees. 2. Find users whose total spending is greater than 5000. 3. Find cities where average salary is above 100,000. 4. Find products sold more than 50 times. 5.
HIRINGMINE CAREER SIGNAL
This writing is proof of expertise.
Explore the author’s verified skills, projects and availability—or start a professional conversation.