Aggregations (COUNT, SUM, AVG) and GROUP BY
Aggregation functions
Section titled “Aggregation functions”Common analytics aggregations:
COUNT(*): number of rowsCOUNT(DISTINCT user_id): unique usersSUM(amount): total revenueAVG(amount): average order amountMIN(),MAX()
SELECT
COUNT(*) AS orders,
SUM(amount) AS revenue,
AVG(amount) AS avg_order_value
FROM orders;GROUP BY
Section titled “GROUP BY”Group by a dimension:
SELECT
u.country,
COUNT(*) AS orders,
SUM(o.amount) AS revenue
FROM orders o
JOIN users u ON u.user_id = o.user_id
GROUP BY u.country
ORDER BY revenue DESC;HAVING
Section titled “HAVING”HAVING filters groups (after aggregation).
SELECT
u.country,
COUNT(*) AS orders
FROM orders o
JOIN users u ON u.user_id = o.user_id
GROUP BY u.country
HAVING COUNT(*) >= 100
ORDER BY orders DESC;Tip: avoid common mistakes
Section titled “Tip: avoid common mistakes”- Every selected non-aggregated column must be in
GROUP BY. WHEREfilters rows before grouping;HAVINGfilters after.
Mental model: split → aggregate → combine
Section titled “Mental model: split → aggregate → combine”GROUP BY works the same way in every SQL dialect: rows are split into buckets by the
grouping column, an aggregate function collapses each bucket to one number, and the buckets
are combined back into a result table — one row per group.
flowchart LR
A["All rows"] --> B{"GROUP BY country"}
B --> C["Bucket: IN"]
B --> D["Bucket: US"]
C --> E["SUM(amount) per bucket"]
D --> E
E --> F["One row per group"]
🧪 Try It Yourself
Section titled “🧪 Try It Yourself”Exercise 1 – COUNT and SUM
Section titled “Exercise 1 – COUNT and SUM”Exercise 2 – GROUP BY a dimension
Section titled “Exercise 2 – GROUP BY a dimension”Exercise 3 – HAVING filters groups
Section titled “Exercise 3 – HAVING filters groups”Now that you can summarize one table, Joins (INNER, LEFT) for Analytics shows you how to bring columns from other tables into that same aggregation.
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading