Understanding the Difference Between WHERE and HAVING in SQL
Introduction
In this lesson we explore why the WHERE clause cannot be used to filter results based on aggregate functions and how the HAVING clause solves this problem.
Why WHERE Fails with Aggregates
WHEREis evaluated before theGROUP BYoperation.- When you try to filter on a column that is the result of an aggregate (e.g.,
AVG(age)), that column does not exist yet because the rows have not been grouped. - Attempting to use
WHERE AVG(age) > 40therefore triggers the error "invalid use of the group by function".
Introducing HAVING
HAVINGis evaluated afterGROUP BYhas created the grouped rows.- It is designed specifically for filtering on aggregate results.
- Syntax change: replace
WHEREwithHAVINGwhen the condition involves an aggregate.
Example 1: Demographics Table
- Query intent: show genders where the average age is greater than 40.
- Original (incorrect) query used
WHERE AVG(age) > 40→ error. - Corrected query:
sql SELECT gender, AVG(age) AS avg_age FROM demographics GROUP BY gender HAVING AVG(age) > 40; - Result: only the gender(s) whose average age exceeds 40 (in the example, males).
Example 2: Salary Table – Combining WHERE and HAVING
- Table contains
occupationandsalarycolumns; two rows for Office Manager with salaries 50,000 and 60,000. - Goal: find managers whose average salary is above 75,000.
- Steps:
- Row‑level filter with
WHEREto keep only occupations that contain the word "manager":sql WHERE occupation LIKE '%manager%' - Group by
occupation. - Aggregate filter with
HAVINGon the average salary:sql HAVING AVG(salary) > 75000 - Full query:
sql SELECT occupation, AVG(salary) AS avg_salary FROM salary WHERE occupation LIKE '%manager%' GROUP BY occupation HAVING AVG(salary) > 75000; - Outcome: rows that satisfy both the row‑level condition (manager) and the aggregate condition (average salary > 75k).
Key Differences Recap
WHERE- Filters rows before grouping.
- Cannot reference aggregate functions.
HAVING- Filters groups after aggregation.
- Used exclusively for conditions on aggregate results.
- In practice,
WHEREis used far more often;HAVINGis reserved for aggregate‑based filtering.
What’s Next?
The next lesson will cover the final beginner topics: LIMIT for restricting result sets and aliasing for clearer column names.
Use WHERE to filter raw rows and HAVING to filter aggregated groups; remembering this order eliminates errors when working with aggregate functions.
Frequently Asked Questions
Who is Alex The Analyst on YouTube?
Alex The Analyst is a YouTube channel that publishes videos on a range of topics. Browse more summaries from this channel below.
Does this page include the full transcript of the video?
Yes, the full transcript for this video is available on this page. Click 'Show transcript' in the sidebar to read it.
Why `WHERE` Fails with Aggregates
- `WHERE` is evaluated **before** the `GROUP BY` operation. - When you try to filter on a column that is the result of an aggregate (e.g., `AVG(age)`), that column does not exist yet because the rows have not been grouped. - Attempting to use `WHERE AVG(age) > 40` therefore triggers the error *"invalid use of the group by function"*.
What’s Next?
The next lesson will cover the final beginner topics: `LIMIT` for restricting result sets and aliasing for clearer column names. Use `WHERE` to filter raw rows and `HAVING` to filter aggregated groups; remembering this order eliminates errors when working with aggregate functions.