Filter rows, then filter groups
Part 1 of 1
Filter rows before groups, groups after aggregation
WHERE removes input rows before aggregation. HAVING removes groups after aggregation. An average over all menu items is different from an average over only expensive items.
A good check reconciles the grouped counts with a total computed on the same filtered population. Matching a number is evidence only when both queries measure the same thing.
Worked example
SELECT category, COUNT(*) AS items FROM menu_items WHERE price >= 5 GROUP BY category HAVING COUNT(*) >= 2 ORDER BY category;
WHERE price >= 5 changes the input population first. GROUP BY collects those expensive items into categories, and HAVING keeps only categories with at least two remaining items.
Moving the count condition into WHERE is not equivalent. Removing WHERE is valid SQL but changes both the category counts and the business question.
Pause and explain. Why would WHERE price >= 3 answer a different question?