Bird
Raised Fist0
SQLquery~5 mins

HAVING clause for filtering groups in SQL

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
Introduction

The HAVING clause helps you filter groups of data after you have grouped them. It works like a filter but for groups, not individual rows.

When you want to find groups with a total count above a certain number, like customers with more than 5 orders.
When you want to filter groups based on the sum or average of a column, like products with total sales over $1000.
When you want to show only groups that meet a condition after grouping, like departments with average salaries above $50,000.
Syntax
SQL
SELECT column1, aggregate_function(column2)
FROM table_name
GROUP BY column1
HAVING condition;
The HAVING clause comes after GROUP BY.
You use aggregate functions like COUNT(), SUM(), AVG() in the HAVING condition.
Examples
This finds departments with more than 3 employees.
SQL
SELECT department, COUNT(*)
FROM employees
GROUP BY department
HAVING COUNT(*) > 3;
This shows products sold in quantities of 100 or more.
SQL
SELECT product_id, SUM(quantity)
FROM sales
GROUP BY product_id
HAVING SUM(quantity) >= 100;
This lists cities where the average salary is above $50,000.
SQL
SELECT city, AVG(salary)
FROM employees
GROUP BY city
HAVING AVG(salary) > 50000;
Sample Program

This query finds customers who made more than 2 orders and shows how many orders and total amount they spent.

SQL
CREATE TABLE orders (
  order_id INT,
  customer_id INT,
  amount DECIMAL(10,2)
);

INSERT INTO orders VALUES
(1, 101, 250.00),
(2, 102, 150.00),
(3, 101, 300.00),
(4, 103, 50.00),
(5, 102, 200.00),
(6, 101, 100.00);

SELECT customer_id, COUNT(*) AS order_count, SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 2;
OutputSuccess
Important Notes

HAVING filters groups after aggregation, unlike WHERE which filters rows before grouping.

You must use GROUP BY with HAVING; otherwise, HAVING acts like WHERE but is less efficient.

Summary

HAVING filters groups created by GROUP BY.

Use aggregate functions in HAVING conditions.

HAVING helps answer questions about groups, like totals or averages.

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