WHERE runs before grouping, so it cannot see an aggregate. HAVING runs after, so it can - and putting the condition in the wrong one is either an error or a different answer.
-- rows first, then group
SELECT customer_id, COUNT(*) AS n
FROM orders
WHERE status = 'PAID' -- per row
GROUP BY customer_id
HAVING COUNT(*) > 3; -- per group
customer_id | n
7 | 5
12 | 4
-- WHERE COUNT(*) > 3 is an error: aggregates do not exist yet.
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-08-25