第 4 课
GROUP BY 与聚合
使用 COUNT、SUM、GROUP BY、HAVING 和时间分桶汇总数据。
聚合会把多行变成汇总行。与其返回每一条订单,不如按状态统计订单数:
SELECT status, COUNT(*) AS order_count
FROM orders
GROUP BY status
ORDER BY order_count DESC;
GROUP BY 决定结果粒度。如果按 status 分组,就是每个状态一行。如果按 status, user_id 分组,就是每个状态和用户组合一行。
WHERE 与 HAVING
WHERE 在分组前过滤原始行:
WHERE created_at >= '2026-01-01'
HAVING 在分组后过滤聚合结果:
HAVING COUNT(*) > 10
报表数字不对时,要确认过滤条件属于聚合前还是聚合后。
时间分桶与数据库方言有关
报表查询经常按天、周、月分组。不同数据库的日期函数不一样。PostgreSQL 可能使用 date_trunc,MySQL 和 SQLite 则有不同函数。
这也是 SQL Formatter 提供方言选项的原因之一。工具知道语言家族后,通常能更好地处理常见结构。
关键结论
读聚合数字前,先确认粒度:一行代表什么?大多数聚合问题来自分组过宽、分组过细,或过滤阶段放错。
可以用 SQL 格式化工具 格式化聚合查询,并标出哪些列决定结果粒度。