GROUP BY buckets rows; aggregates summarize each bucket; HAVING filters the groups.
Collapse many rows into one summary per group — totals per customer, averages per day, counts per category.
Every metric, every feature, every dashboard number is an aggregation, and the WHERE/HAVING distinction is a standard interview check.
GROUP BY collapses rows that share a key into one row per group, and aggregate functions — COUNT, SUM, AVG, MIN, MAX — reduce each group to a single value. WHERE filters individual rows before grouping; HAVING filters the resulting groups by their aggregates. The two filters run at different stages and are not interchangeable.
GROUP BY buckets rows by a key and computes one aggregate per bucket. WHERE filters rows before grouping and can't see aggregates; HAVING filters groups after aggregation and can. Any non-aggregated column in SELECT must appear in GROUP BY.
Intermediate SQL Tutorial | Having Clause — Alex The Analyst, 3:31