Skip to content
SPM Tuition
Computer Science · SQL reasoning in a fictional database

Row filtering versus group filtering

WHERE and HAVING both filter, so you keep using the wrong one.

WHERE filters individual rows before grouping. HAVING filters groups after the totals are worked out.

This lesson belongs to SQL reasoning in a fictional database. It builds on using aggregation and filtering.

What are we working with?

Use this original Sales table, with amounts in RM.

SaleID Branch Item Amount
1 Ampang Pen 12
2 Ampang Bag 45
3 Ampang Book 30
4 Bangi Bag 50
5 Bangi Pen 8
6 Bangi Book 22
7 Cheras Pen 15
8 Cheras Book 18

Worked example: one query, step by step

SELECT Branch, SUM(Amount)
FROM Sales
WHERE Amount >= 20
GROUP BY Branch
HAVING SUM(Amount) >= 73;

Step 1: WHERE removes rows. Keep rows with Amount of at least 20. These are sale 2 (Ampang, 45), sale 3 (Ampang, 30), sale 4 (Bangi, 50) and sale 6 (Bangi, 22). Four rows remain, and all Cheras rows are gone.

Step 2: GROUP BY forms groups. Ampang has 45 and 30. Bangi has 50 and 22.

Step 3: SUM totals each group. Ampang: 45 + 30 = 75. Bangi: 50 + 22 = 72.

Step 4: HAVING removes groups. Keep groups with a total of at least 73. Ampang (75) stays, and Bangi (72) is removed.

Output.

Branch SUM(Amount)
Ampang 75

What changes without the WHERE line?

Remove WHERE Amount >= 20 and run the same query.

Branch Total of all rows Passes HAVING (at least 73)?
Ampang 12 + 45 + 30 = 87 yes
Bangi 50 + 8 + 22 = 80 yes
Cheras 15 + 18 = 33 no

Now two branches appear, with bigger totals. The small sales that WHERE removed were still counted.

The mistake that costs marks

Students write WHERE SUM(Amount) >= 73. The system rejects it, because SUM cannot exist before grouping.

Wrong Right
WHERE SUM(Amount) >= 73 HAVING SUM(Amount) >= 73

The fix is to ask what the condition is about. A condition on one row’s column goes in WHERE. A condition on a total, count or average goes in HAVING.

Check yourself

Using the Sales table, what does this query return?

SELECT Branch, COUNT(*)
FROM Sales
WHERE Item = 'Pen'
GROUP BY Branch
HAVING COUNT(*) >= 1;
Answer

WHERE keeps the Pen rows: sale 1 (Ampang), sale 5 (Bangi) and sale 7 (Cheras). Each branch then has one Pen sale, so each group has COUNT of 1, which passes HAVING. The output has three rows: Ampang 1, Bangi 1, Cheras 1.

What to study next

Groups can also be empty or contain missing values. Continue with testing an aggregate query with empty groups and missing values, then revisit using aggregation and filtering.

If you want a teacher to trace queries with you, see online one-to-one Computer Science tuition.

Common questions

What is the difference between WHERE and HAVING?

WHERE removes individual rows before any grouping happens. HAVING removes whole groups after the totals have been calculated. Use WHERE for a condition on a column of one row, and HAVING for a condition on a total, count or average.

Can I use SUM in a WHERE clause?

No. The totals do not exist yet when WHERE runs, because rows have not been grouped. A condition on SUM, COUNT or AVG belongs in HAVING.

Which runs first?

WHERE runs first, then GROUP BY, then HAVING. Think of it as filter rows, form groups, total each group, then filter the groups.

If WHERE and HAVING still blur together, one-to-one Computer Science lessons let a teacher give you queries to trace and ask you which step removes each row.

  • Online one-to-one lessons for your child with an experienced teacher.
  • Your first class is a one-hour trial, from RM50. The fee is agreed before you book.
  • Happy with the teacher? Continue with lessons of about 1.5 hours. If not, ask for another teacher.