Example 1
Filter grouped customers after counting orders
WHERE status = 'paid' removes Carol's cancelled row before grouping starts. The grouped result then contains Alice with 2 paid orders and Bob with 1. HAVING COUNT(*) > 1 runs after grouping and keeps only Alice.
CREATE TABLE orders (
id INT,
customer_name VARCHAR(50),
status VARCHAR(20)
);
INSERT INTO
orders (id, customer_name, status)
VALUES
(1, 'Alice', 'paid'),
(2, 'Alice', 'paid'),
(3, 'Bob', 'paid'),
(4, 'Carol', 'cancelled');SELECT
customer_name,
COUNT(*) AS paid_orders
FROM
orders
WHERE
status = 'paid'
GROUP BY
customer_name
HAVING
COUNT(*) > 1
ORDER BY
customer_name;| customer_name | paid_orders |
|---|---|
| Alice | 2 |
`WHERE` reduces the input rows first, then `HAVING` filters the grouped totals.