WHERE filters rows before grouping; HAVING filters groups after. Use HAVING COUNT(*) > 1 to find duplicates.
You can use both in one query: WHERE status = 'paid' … GROUP BY … HAVING SUM(amount) > 1000.
Worked example
Which countries have more than three customers?
SELECT country, COUNT(*) AS customers FROM customers GROUP BY country HAVING COUNT(*) > 3;
| country | customers |
|---|---|
| Germany | 4 |
Common mistakes
- Putting an aggregate condition in WHERE, which raises an error.
- Using HAVING for row filters that belong in WHERE, which is slower and harder to read.