Bird
Raised Fist0
PostgreSQLquery~10 mins

HAVING for filtering groups in PostgreSQL - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - HAVING for filtering groups
Start with Table Data
↓
GROUP BY specified columns
↓
Calculate aggregates per group
↓
Apply HAVING condition on groups
Yes | No↓
Exclude group
↓
Return groups that meet HAVING condition
Data is grouped by columns, aggregates are calculated, then HAVING filters groups based on conditions.
Execution Sample
PostgreSQL
SELECT department, COUNT(*) AS emp_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 2;
This query groups employees by department and returns only departments with more than 2 employees.
Execution Table
StepActionGroups FormedAggregate CalculatedHAVING ConditionGroup Included?
1Group employees by department[Sales, HR, IT]Count employees in each groupN/AN/A
2Calculate counts[Sales=3, HR=2, IT=4]Sales=3, HR=2, IT=4N/AN/A
3Apply HAVING COUNT(*) > 2Same groupsSame countsSales: 3 > 2 = TrueYes
4Apply HAVING COUNT(*) > 2Same groupsSame countsHR: 2 > 2 = FalseNo
5Apply HAVING COUNT(*) > 2Same groupsSame countsIT: 4 > 2 = TrueYes
6Return filtered groups[Sales, IT]Counts: 3, 4Condition metIncluded
💡 All groups checked; only those with count > 2 are included.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
GroupsNone[Sales, HR, IT][Sales=3, HR=2, IT=4][Sales=3, HR=2, IT=4][Sales=3, IT=4]
HAVING Condition ResultN/AN/AN/A[True, False, True][True, False]
Key Moments - 2 Insights
Why doesn't HAVING filter individual rows like WHERE?
HAVING filters after grouping and aggregation (see execution_table rows 3-5), so it works on groups, not single rows.
What happens if HAVING condition is false for a group?
That group is excluded from the final result (see execution_table row 4 where HR group is excluded).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 4, what is the HAVING condition result for HR group?
ATrue
BNot evaluated
CFalse
DError
💡 Hint
Check the 'HAVING Condition' column at step 4 for HR group.
At which step are groups formed from the table data?
AStep 2
BStep 1
CStep 3
DStep 6
💡 Hint
Look at the 'Action' column to find when grouping happens.
If HAVING condition changed to COUNT(*) > 4, which groups would be included?
ANo groups
BOnly IT
COnly Sales
DSales and IT
💡 Hint
Refer to 'Aggregate Calculated' counts and compare with new condition.
Concept Snapshot
HAVING filters groups after GROUP BY and aggregation.
Syntax: SELECT columns FROM table GROUP BY columns HAVING condition;
HAVING works on aggregated data, unlike WHERE.
Use HAVING to filter groups, e.g., HAVING COUNT(*) > 2.
Groups failing HAVING condition are excluded from results.
Full Transcript
The HAVING clause filters groups formed by GROUP BY after aggregates are calculated. First, data is grouped by specified columns. Then, aggregate functions like COUNT calculate values per group. HAVING applies conditions on these aggregates to decide which groups to keep. Groups not meeting the HAVING condition are excluded from the final output. This differs from WHERE, which filters rows before grouping. For example, grouping employees by department and counting them, HAVING COUNT(*) > 2 returns only departments with more than two employees.

Practice

(1/5)
1. What is the main purpose of the HAVING clause in a PostgreSQL query?
easy
A. To join two tables
B. To filter rows before grouping
C. To sort the result set
D. To filter groups after aggregation

Solution

  1. Step 1: Understand the role of HAVING

    The HAVING clause is used to filter groups created by GROUP BY based on aggregate conditions.
  2. Step 2: Differentiate HAVING from WHERE

    WHERE filters rows before grouping, HAVING filters groups after aggregation.
  3. Final Answer:

    To filter groups after aggregation -> Option D
  4. Quick Check:

    HAVING filters groups = D [OK]
Hint: Remember HAVING filters groups, WHERE filters rows [OK]
Common Mistakes:
  • Confusing HAVING with WHERE clause
  • Thinking HAVING sorts data
  • Using HAVING without GROUP BY
2. Which of the following is the correct syntax to filter groups having a total sales greater than 1000 using HAVING?
easy
A. SELECT store, SUM(sales) FROM sales_data HAVING SUM(sales) > 1000 GROUP BY store;
B. SELECT store, SUM(sales) FROM sales_data GROUP BY store HAVING SUM(sales) > 1000;
C. SELECT store, SUM(sales) FROM sales_data WHERE SUM(sales) > 1000 GROUP BY store;
D. SELECT store, SUM(sales) FROM sales_data GROUP BY store WHERE SUM(sales) > 1000;

Solution

  1. Step 1: Identify correct order of clauses

    GROUP BY must come before HAVING in SQL syntax.
  2. Step 2: Check aggregate usage in HAVING

    HAVING uses aggregate functions like SUM(sales) to filter groups.
  3. Final Answer:

    SELECT store, SUM(sales) FROM sales_data GROUP BY store HAVING SUM(sales) > 1000; -> Option B
  4. Quick Check:

    GROUP BY before HAVING = B [OK]
Hint: HAVING always follows GROUP BY clause [OK]
Common Mistakes:
  • Placing HAVING before GROUP BY
  • Using WHERE with aggregate functions
  • Incorrect clause order
3. Given the table orders with columns customer_id and amount, what will this query return?
SELECT customer_id, COUNT(*) FROM orders GROUP BY customer_id HAVING COUNT(*) > 2;
medium
A. All customers with more than 2 orders
B. All customers with exactly 2 orders
C. All customers with less than 2 orders
D. Syntax error due to HAVING clause

Solution

  1. Step 1: Understand the GROUP BY and COUNT(*)

    The query groups rows by customer_id and counts orders per customer.
  2. Step 2: Apply HAVING filter

    HAVING COUNT(*) > 2 keeps only customers with more than 2 orders.
  3. Final Answer:

    All customers with more than 2 orders -> Option A
  4. Quick Check:

    HAVING COUNT(*) > 2 filters groups with >2 rows [OK]
Hint: HAVING filters groups by aggregate results [OK]
Common Mistakes:
  • Confusing > 2 with = 2
  • Thinking HAVING causes syntax error
  • Ignoring GROUP BY effect
4. Identify the error in this query:
SELECT department, AVG(salary) FROM employees HAVING AVG(salary) > 50000 GROUP BY department;
medium
A. HAVING clause used before GROUP BY
B. AVG() cannot be used in HAVING
C. Missing WHERE clause before HAVING
D. No error, query is correct

Solution

  1. Step 1: Check clause order

    SQL requires GROUP BY before HAVING clause.
  2. Step 2: Identify error in query

    HAVING appears before GROUP BY, which is invalid syntax.
  3. Final Answer:

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

    GROUP BY must precede HAVING [OK]
Hint: GROUP BY comes before HAVING always [OK]
Common Mistakes:
  • Placing HAVING before GROUP BY
  • Assuming AVG() not allowed in HAVING
  • Confusing WHERE and HAVING
5. You have a sales table with columns region, salesperson, and amount. Write a query to find regions where the total sales exceed 10,000 but only include salespeople who individually sold more than 3,000. Which query correctly applies HAVING to achieve this?
hard
A. SELECT region, salesperson, SUM(amount) FROM sales GROUP BY region, salesperson HAVING SUM(amount) > 3000 AND SUM(amount) > 10000;
B. SELECT region, SUM(amount) FROM sales GROUP BY region HAVING SUM(amount) > 10000 AND salesperson IN (SELECT salesperson FROM sales GROUP BY salesperson HAVING SUM(amount) > 3000);
C. SELECT region, salesperson, SUM(amount) FROM sales GROUP BY region, salesperson HAVING SUM(amount) > 3000 AND region IN (SELECT region FROM sales GROUP BY region HAVING SUM(amount) > 10000);
D. SELECT region, salesperson, SUM(amount) FROM sales WHERE SUM(amount) > 3000 GROUP BY region, salesperson HAVING SUM(amount) > 10000;

Solution

  1. Step 1: Understand filtering conditions

    We want regions with total sales > 10,000 and salespeople with sales > 3,000.
  2. Step 2: Analyze correct logic

    Group by region and salesperson, filter salespeople with >3000 sales using HAVING SUM(amount) > 3000, and filter regions with total sales > 10000 using a subquery in HAVING: region IN (SELECT region FROM sales GROUP BY region HAVING SUM(amount) > 10000).
  3. Step 3: Check HAVING usage

    This correctly applies HAVING on both salesperson and region aggregates using subquery.
  4. Final Answer:

    SELECT region, salesperson, SUM(amount) FROM sales GROUP BY region, salesperson HAVING SUM(amount) > 3000 AND region IN (SELECT region FROM sales GROUP BY region HAVING SUM(amount) > 10000); -> Option C
  5. Quick Check:

    Use HAVING with subqueries for multi-level group filters [OK]
Hint: Use HAVING with subqueries for multi-level group filters [OK]
Common Mistakes:
  • Using WHERE with aggregate functions
  • Incorrect clause order
  • Combining unrelated HAVING conditions without subqueries
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard