SQL Tutorial 0/85 lessons ~6 min read Lesson 28
HAVING Clause
HAVING filters groups, not rows.
Course progress0%
Focus
6 guided sections
Practice signal
Examples included
Career prep
Foundation builder
Introduction
HAVING filters groups, not rows. It runs after GROUP BY. Use WHERE to filter rows before grouping; HAVING to filter the resulting groups.
Understanding the topic
Core concepts to understand:
- Runs after GROUP BY.
- Can reference aggregates:
HAVING sum(amount) > 1000. - Cannot reference column aliases in standard SQL (Postgres allows it).
- Combine with WHERE to filter both rows and groups.
- Equivalent to a wrapper subquery on the grouped result.
Syntax reference
Visual workflow / architecture:
bash
WHERE status = 'paid' -- row filterGROUP BY user_idHAVING sum(amount) > 1000 -- group filterORDER BY sum(amount) DESC;
Syntax Pattern
SELECT <group_col>, <agg_func>(<col>) AS <alias> FROM <table> GROUP BY <group_col> HAVING <agg_predicate>;
HAVINGFilters groups AFTER aggregation.WHEREFilters rows BEFORE aggregation.aliasMost engines allow referencing the agg alias here.
Live Example
sql
SELECT plan, COUNT(*) AS usersFROM usersGROUP BY planHAVING COUNT(*) >= 3;
grouped
| plan | users |
|---|---|
| free | 2 |
| pro | 3 |
| enterprise | 1 |
runs
after HAVING
| plan | users |
|---|---|
| pro | 3 |
WHERE filter
drops rows that don't match
HAVING is the WHERE-clause for groups.
Real-world use
Show top-spending customers, products with > 100 sales, regions with > 5 errors — classic HAVING queries.
Best practices
- Push as much as possible into WHERE for performance.
- Use HAVING only for aggregate filters.
- Index columns used in WHERE/GROUP BY.
Hands-on exercise
Interview preparation — practice these questions:
- Q1. Difference between HAVING and WHERE.
- Q2. Order of execution: WHERE/GROUP BY/HAVING.
- Q3. Can HAVING use aggregates?
- Q4. Can WHERE use aggregates?
- Q5. Example using both.
Ready to mark this lesson complete?Track your journey across the entire course.