第二章|聚合、分组与汇总
本章目标
学习如何使用聚合函数对数据进行统计和汇总,掌握 GROUP BY 分组、HAVING 过滤,理解聚合与普通查询的区别。
从简单的 COUNT 和 SUM 开始,理解聚合函数的工作原理,学会用 GROUP BY 按列分组,用 HAVING 过滤分组结果,最后掌握多列分组和 ROLLUP 小计。
学习路径
按顺序阅读以下文章,每篇包含讲解、示例和练习:
聚合函数:COUNT、SUM、AVG、MIN、MAX
使用聚合函数统计数据,理解聚合函数与普通列的区别。GROUP BY:按列分组
按一列或多列分组,对每组进行聚合计算。HAVING:分组后过滤
使用 HAVING 过滤分组结果,理解 WHERE 和 HAVING 的区别。多列分组与 ROLLUP
按多列分组,使用 ROLLUP 生成小计和总计。
关键概念
聚合函数将多行合并为一行
聚合函数对一组行进行计算,返回单个值:
sql
-- 普通 SELECT:返回多行
SELECT age FROM users;
-- 结果:30, 25, 35, 28, NULL(5 行)
-- 聚合 SELECT:返回一行
SELECT COUNT(*) FROM users;
-- 结果:5(1 行)GROUP BY 创建分组
GROUP BY 将数据分成多个组,对每组分别聚合:
sql
-- 每个年龄段有多少人
SELECT age, COUNT(*)
FROM users
GROUP BY age;结果:每个不同的年龄对应一行聚合结果。
WHERE vs HAVING
- WHERE:在分组前过滤行(基于原始数据)
- HAVING:在分组后过滤组(基于聚合结果)
sql
-- WHERE:年龄大于 25 的用户有多少人
SELECT COUNT(*) FROM users WHERE age > 25;
-- HAVING:哪些年龄段有超过 1 个人
SELECT age, COUNT(*)
FROM users
GROUP BY age
HAVING COUNT(*) > 1;执行顺序
sql
SELECT column, aggregate_function(column) -- 5. 选择列和聚合结果
FROM table -- 1. 从表中获取数据
WHERE condition -- 2. 过滤行
GROUP BY column -- 3. 分组
HAVING aggregate_condition -- 4. 过滤分组
ORDER BY column -- 6. 排序
LIMIT n; -- 7. 限制行数前置知识
- 掌握 SELECT、WHERE、ORDER BY(第一章)
- 理解 NULL 的处理
- 能够创建表和插入数据
后续章节
完成本章后,继续学习:
第三章:连接、子查询与集合
掌握 INNER JOIN、LEFT JOIN、子查询、EXISTS、UNION。第四章:窗口函数与高级查询
学习窗口函数、CTE、递归查询。
练习答案
本章所有练习的答案和详细解释:第二章练习答案
深入阅读
为什么 SELECT 中不能混用聚合和非聚合列?
sql
-- 错误
SELECT name, COUNT(*) FROM users;这个查询有歧义:name 是多行,COUNT(*) 是一行,数据库不知道应该返回几行。正确做法是要么只用聚合函数,要么用 GROUP BY。
NULL 在聚合中如何处理?
大多数聚合函数会忽略 NULL:
COUNT(*)计数所有行(包括 NULL)COUNT(column)只计数非 NULL 行SUM/AVG/MIN/MAX忽略 NULL