HAVING
WHERE filters source rows; HAVING filters the groups built from those rows.
Before versus after grouping
WHERE status = 'paid' first removes non-paid orders. GROUP BY then builds customer groups. HAVING COUNT(*) >= 2 retains groups with at least two remaining orders.
Group-level conditions
Use aggregate expressions in HAVING, such as SUM(sales) > 200. An aggregate cannot normally be used directly in WHERE because the groups do not exist at that stage.
Read the question closely
“Customers with two paid orders” differs from “customers with two orders and some paid activity”. The first counts after filtering; the second requires separate conditions or conditional aggregation.
Keep it portable
Some databases accept SELECT aliases in HAVING; others do not. Repeating the aggregate expression is a broadly portable choice. HAVING can also apply to a single aggregate group without GROUP BY.