Bird
Raised Fist0
SQLquery~10 mins

HAVING clause for filtering groups in SQL - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - HAVING clause for filtering groups
Start with Table Data
GROUP BY columns
Aggregate functions calculate
Apply HAVING condition on groups
Yes | No
Output groups that pass HAVING
END
The HAVING clause filters groups after aggregation, only outputting groups that meet the condition.
Execution Sample
SQL
SELECT department, COUNT(*) AS emp_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 2;
This query counts employees per department and shows only departments with more than 2 employees.
Execution Table
StepActionData StateResult
1Read all employee rowsemployees table with multiple departmentsAll rows loaded
2Group rows by departmentGroups formed: Sales(3), HR(2), IT(4)3 groups created
3Calculate COUNT(*) for each groupSales=3, HR=2, IT=4Counts computed
4Apply HAVING COUNT(*) > 2Sales=3 (passes), HR=2 (fails), IT=4 (passes)Sales and IT groups kept
5Output filtered groupsDepartments Sales and IT with countsFinal result with 2 rows
6End of queryNo more stepsQuery complete
💡 HAVING filters out HR group because count 2 is not > 2
Variable Tracker
VariableStartAfter GroupingAfter AggregationAfter HAVINGFinal
GroupsnoneSales(3), HR(2), IT(4)Sales=3, HR=2, IT=4Sales=3, IT=4Sales=3, IT=4
Output RowsnonenonenoneSales, ITSales, IT
Key Moments - 2 Insights
Why doesn't HAVING work like WHERE for filtering individual rows?
HAVING filters after grouping and aggregation, so it works on groups, not individual rows. See execution_table step 4 where groups are filtered after counts are calculated.
What happens if HAVING condition is false for all groups?
No groups are output, resulting in an empty result set. This is shown in execution_table step 4 where HR group is removed because it fails the condition.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the count for the IT group after aggregation?
A3
B4
C2
D5
💡 Hint
Check the 'After Aggregation' column in execution_table row 3 for IT group count.
At which step does the HAVING clause filter out groups?
AStep 2
BStep 3
CStep 4
DStep 5
💡 Hint
Look at the 'Action' column in execution_table to find when HAVING is applied.
If the HAVING condition was changed to COUNT(*) > 4, which groups would remain?
ANo groups
BSales and IT
COnly Sales
DOnly IT
💡 Hint
Refer to variable_tracker for group counts and compare with new condition.
Concept Snapshot
HAVING clause filters groups after aggregation.
Syntax: SELECT columns FROM table GROUP BY columns HAVING condition;
HAVING works on aggregated data, unlike WHERE.
Use HAVING to filter groups based on aggregate results.
Groups failing HAVING condition are excluded from output.
Full Transcript
The HAVING clause is used in SQL to filter groups after the data has been grouped and aggregate functions have been calculated. First, the database reads all rows from the table. Then it groups rows by the specified columns. Next, aggregate functions like COUNT calculate values for each group. After that, the HAVING clause filters these groups based on the condition provided. Only groups that meet the condition are included in the final output. For example, if we group employees by department and count them, HAVING COUNT(*) > 2 will only show departments with more than two employees. This differs from WHERE, which filters rows before grouping. If no groups meet the HAVING condition, the result is empty. This step-by-step process helps understand how HAVING works to filter grouped data.

Practice

(1/5)
1.

What is the main purpose of the HAVING clause in SQL?

easy
A. To filter individual rows before grouping
B. To sort the results of a query
C. To filter groups created by GROUP BY based on aggregate conditions
D. To join two tables together

Solution

  1. Step 1: Understand the role of GROUP BY

    The GROUP BY clause groups rows based on column values.
  2. Step 2: Identify the purpose of HAVING

    HAVING filters these groups using aggregate functions like SUM or COUNT.
  3. Final Answer:

    To filter groups created by GROUP BY based on aggregate conditions -> Option C
  4. Quick Check:

    HAVING filters groups, not rows [OK]
Hint: Remember: WHERE filters rows, HAVING filters groups [OK]
Common Mistakes:
  • Confusing HAVING with WHERE clause
  • Using HAVING without GROUP BY
  • Thinking HAVING sorts data
2.

Which of the following is the correct syntax to filter groups with HAVING?

SELECT department, COUNT(*) FROM employees GROUP BY department _______ COUNT(*) > 5;
easy
A. GROUP BY
B. WHERE
C. FILTER
D. HAVING

Solution

  1. Step 1: Identify filtering clause after grouping

    After GROUP BY, filtering groups requires HAVING, not WHERE.
  2. Step 2: Confirm correct clause usage

    HAVING COUNT(*) > 5 filters groups with more than 5 employees.
  3. Final Answer:

    HAVING -> Option D
  4. Quick Check:

    Use HAVING after GROUP BY [OK]
Hint: Use HAVING to filter groups, not WHERE [OK]
Common Mistakes:
  • Using WHERE instead of HAVING after GROUP BY
  • Placing HAVING before GROUP BY
  • Using FILTER keyword which is invalid here
3.

Given the table sales with columns region and amount, what will this query return?

SELECT region, SUM(amount) FROM sales GROUP BY region HAVING SUM(amount) > 1000;
medium
A. All regions with total sales greater than 1000
B. All regions with total sales less than or equal to 1000
C. All sales records with amount greater than 1000
D. Syntax error due to HAVING clause

Solution

  1. Step 1: Group sales by region and sum amounts

    The query groups rows by region and calculates total amount per region.
  2. Step 2: Filter groups with total sales > 1000

    The HAVING clause keeps only regions where the sum is greater than 1000.
  3. Final Answer:

    All regions with total sales greater than 1000 -> Option A
  4. Quick Check:

    HAVING filters groups by aggregate sum [OK]
Hint: HAVING filters groups by aggregate results [OK]
Common Mistakes:
  • Thinking HAVING filters individual rows
  • Confusing SUM(amount) with amount column
  • Assuming syntax error with HAVING
4.

Identify the error in this query:

SELECT category, COUNT(*) FROM products HAVING COUNT(*) > 10 GROUP BY category;
medium
A. Missing WHERE clause before HAVING
B. HAVING clause used before GROUP BY
C. COUNT(*) cannot be used in HAVING
D. GROUP BY should be replaced with ORDER BY

Solution

  1. Step 1: Check order of clauses in SQL

    The correct order is GROUP BY first, then HAVING.
  2. Step 2: Identify incorrect clause order

    The query places HAVING before GROUP BY, causing syntax error.
  3. Final Answer:

    HAVING clause used before GROUP BY -> Option B
  4. Quick Check:

    GROUP BY before HAVING [OK]
Hint: GROUP BY must come before HAVING [OK]
Common Mistakes:
  • Placing HAVING before GROUP BY
  • Thinking HAVING needs WHERE before it
  • Replacing GROUP BY with ORDER BY incorrectly
5.

You have a students table with columns class and score. You want to find classes where the average score is at least 75 and the number of students is more than 10. Which query achieves this?

hard
A. SELECT class, AVG(score), COUNT(*) FROM students GROUP BY class HAVING AVG(score) >= 75 AND COUNT(*) > 10;
B. SELECT class, AVG(score), COUNT(*) FROM students HAVING AVG(score) >= 75 AND COUNT(*) > 10 GROUP BY class;
C. SELECT class, AVG(score), COUNT(*) FROM students WHERE AVG(score) >= 75 AND COUNT(*) > 10 GROUP BY class;
D. SELECT class, AVG(score), COUNT(*) FROM students GROUP BY class WHERE AVG(score) >= 75 AND COUNT(*) > 10;

Solution

  1. Step 1: Group students by class

    Use GROUP BY class to group rows by class.
  2. Step 2: Filter groups with HAVING using aggregate conditions

    Use HAVING AVG(score) >= 75 AND COUNT(*) > 10 to keep classes meeting both conditions.
  3. Final Answer:

    SELECT class, AVG(score), COUNT(*) FROM students GROUP BY class HAVING AVG(score) >= 75 AND COUNT(*) > 10; -> Option A
  4. Quick Check:

    HAVING filters groups by multiple aggregates [OK]
Hint: Use HAVING for multiple aggregate filters after GROUP BY [OK]
Common Mistakes:
  • Placing HAVING before GROUP BY
  • Using WHERE with aggregate functions
  • Putting WHERE after GROUP BY