本章要回答的三个问题:COUNT、SUM、AVG 这些聚合函数把多行折叠成一个数,折叠时 NULL 是被算进去还是被跳过?GROUP BY 按什么折叠、为什么 SELECT 里出现"分组列之外"的列会直接报错?分组之后还想再筛选,为什么 WHERE 无能为力、必须换 HAVING?本章是 SQL 思维的第一次跃迁:从"看行"到"看组"。
业务提问的方式变了。"库存总量多少""每个分类平均定价多少""哪些分类的书超过三种"——这些问题没有一行数据能直接回答,它们问的是一堆行的共同属性。聚合函数负责"算这一堆",GROUP BY 负责"划定哪一堆",HAVING 负责"把不达标的一堆扔掉"。三件套合起来,你才能从明细数据里产出报表。
这一章也是整个阶梯上承前启后的枢纽。向前看,第 3 章的表达式与 CASE 会在聚合里大显身手(条件计数、条件求和);向后看,GROUP BY 折叠明细行这个"天性",恰好是第 7 章窗口函数登场的理由——想要"每组汇总值 + 每行明细"同屏显示,GROUP BY 做不到,窗口函数做得到。理解了 GROUP BY 的局限,才算真正理解窗口函数存在的意义。
| 节 | 回答哪个问题 | 关键产出 |
|---|---|---|
| 4.1 聚合函数与 COUNT 的三种数法 | 折叠时怎么算 | 五大聚合函数、NULL 处理规则、DISTINCT 的位置 |
| 4.2 GROUP BY 与 HAVING | 按什么折叠、折后怎么筛 | 分组机制、SELECT 列限制、WHERE/HAVING 流水线 |
聚合的本质是"牺牲明细换洞察":每组只剩一个数,行没了。记住这笔交易的代价,第 7 章你会看到不用付这笔账的另一种聚合。
单表之内能查能算能分组,但书店的数据散在七张表里:书名在 books、买家在 customers、订单在 orders。下一章走出单表,用 JOIN 把拆开的世界拼回来——先回答"当初为什么要拆"。