SQL GROUP BY
GROUP BY 按一个或多个键把结果行分组,为 COUNT、SUM、AVG 等聚合函数提供计算粒度。
#concept
#growing
#backend
#sql
#database
[!info] related notes
- 所属 MOC: database-moc
- 前置概念: sql-join、query
- 并列概念: sql-aggregate-functions
- 易混淆概念:
- 关系笔记: sql-join-group-by-and-aggregation、sql-having-vs-where
SQL GROUP BY
一句话定义
GROUP BY 按一个或多个表达式把结果行划分成组,使聚合函数能够针对“每一组”计算一个结果。
核心机制
SELECT user_id, COUNT(*) AS order_count
FROM orders
GROUP BY user_id;
可以把它理解为先按 user_id 建 bucket:
user 1 -> order A, B, C
user 2 -> order D
然后每个 bucket 分别执行 COUNT。
SELECT 与分组粒度
用了 GROUP BY 后,SELECT 中的值必须能在“每一组”上得到唯一意义:
- 分组键可以直接输出;
- 其他列通常要经过聚合函数。
SELECT user_id, SUM(amount)
FROM orders
GROUP BY user_id;
否则数据库无法知道一组多行中应该取哪一个普通列值。部分数据库会利用函数依赖做额外推断,但学习和跨数据库写法应先坚持这个基本规则。
GROUP BY 不等于排序
GROUP BY 定义分组,不承诺最终输出顺序。需要稳定顺序时显式使用:
ORDER BY ...
与 DISTINCT 的区别
DISTINCT 主要去除重复结果;GROUP BY 的核心价值是建立聚合粒度。只做去重时二者有时能得到相同结果,但语义目的不同。
与 WHERE / HAVING 的位置
心智模型:
FROM / JOIN
→ WHERE 过滤原始行
→ GROUP BY 分组
→ 聚合计算
→ HAVING 过滤组
→ SELECT / ORDER BY
因此“只统计 paid 订单”用 WHERE,“只保留订单数 >= 3 的用户”用 HAVING。
边界与常见误解
- 分组键越细,组越小;先明确业务统计粒度再写 SQL。
- 多表 JOIN 后再 GROUP BY 时,要警惕 JOIN 造成重复行,从而把 COUNT/SUM 放大。
GROUP BY是逻辑语义;数据库物理执行可能选择 Hash Aggregate、Sort Aggregate 等不同计划。