告别一行行数数据,一招搞定统计汇总
大家好呀!我是数据库小学妹👋一个正在从设计转行学数据库的"萌新"。
前几篇我们学了怎么查数据、怎么排序、怎么筛选、怎么连表。但有个问题一直困扰我:
如果我想知道“班里有多少人?”
“数学平均分是多少?”
“每个部门各有几个员工?”
……
难道要一行行去数吗?
当然不是!今天我就把自己学到的数据汇总神器分享出来,让你用几句SQL就能搞定统计。
一、从一个真实场景说起
假设你有一张学生成绩表 score,记录了每个学生的姓名、班级、科目和分数。
| name | class | subject | score |
|---|---|---|---|
| 小明 | 1班 | 数学 | 90 |
| 小红 | 1班 | 数学 | 85 |
| 小刚 | 2班 | 数学 | 92 |
| 小明 | 1班 | 语文 | 88 |
| 小红 | 1班 | 语文 | 90 |
| 小刚 | 2班 | 语文 | 86 |
问:“1班数学考试有多少人参加?平均分多少?最高分是多少?”
如果用Excel,你可能需要筛选、拖公式。但在数据库里,聚合函数一键就可以搞定。
二、五大聚合函数:统计界的“五虎将”
聚合函数就是对一组数据做计算,返回一个单一结果。就像用计算器求和、求平均一样。
💡如果从设计师的视角来说,聚合函数就像设计软件里面的 统计面板——一键显示图层数量、颜色数量、文件大小。
🛠️实战演练
-- 1班数学考试有多少人?
SELECT COUNT(*) FROM score
WHERE class = '1班' AND subject = '数学';
-- 结果:2(小明和小红)
-- 1班数学平均分是多少?
SELECT AVG(score) FROM score
WHERE class = '1班' AND subject = '数学';
-- 结果:(90+85)/2 = 87.5
-- 1班数学最高分?
SELECT MAX(score) FROM score
WHERE class = '1班' AND subject = '数学';
-- 结果:90
💡 小细节:
COUNT(*)统计所有行,COUNT(列名)只统计该列非空的行。如果某列是NULL,COUNT(列名)会忽略它。
三、GROUP BY:一键分组统计
上面的例子只能看一个班级。如果我想看每个班级的数学平均分,难道要一个一个写条件吗?
不用!GROUP BY 就是用来分组的。
SELECT class, AVG(score)
FROM score
WHERE subject = '数学'
GROUP BY class;
结果:
| class | AVG(score) |
|---|---|
| 1班 | 87.5 |
| 2班 | 92 |
GROUP BY 就像设计软件里的智能分组,自动把相同班级的数据分成一组,然后对每组分别计算平均值。
注意: SELECT 后面只能放两种东西:
- 被分组的列(如
class) - 聚合函数(如
AVG(score))
如果写成 SELECT name, AVG(score) ... GROUP BY class,就会报错,因为 name 不在分组里,数据库不知道选哪个 name。
四、HAVING:分组后的筛选
WHERE 是在分组前筛选数据,HAVING 是在分组后筛选分组结果。
比如:找出平均分大于90的班级。
SELECT class, AVG(score) as avg_score
FROM score
WHERE subject = '数学'
GROUP BY class
HAVING avg_score > 90;
| class | avg_score |
|---|---|
| 2班 | 92 |
WHERE vs HAVING 一句话记清楚:
WHERE过滤行(分组前)HAVING过滤组(分组后)
五、结合JOIN:多表分组统计
我们之前学过JOIN,现在可以把两张表连起来再做统计。比如:查每个班级的平均分(班级名称在班级表,成绩在成绩表)。
SELECT c.class_name, AVG(sc.score) as avg_score
FROM students s
INNER JOIN scores sc ON s.id = sc.student_id
INNER JOIN classes c ON s.class_id = c.id
GROUP BY c.class_name;
先JOIN拼成大表,再GROUP BY分组,完美!
六、新手避坑指南(血泪总结)

我踩过的坑:想统计每个班级的平均分,结果忘了写 GROUP BY,返回了整个表的平均分,还纳闷了半天为什么结果只有一行……
七、今日学习心得
📝核心总结(三句话):
- 聚合函数:对一组数据做统计(COUNT、SUM、AVG、MAX、MIN)
- GROUP BY:按某个字段分组,每组分别统计
- HAVING:对分组后的结果再筛选
把它们组合起来,就能回答各种“按xx统计”的问题。比如:
- 每个月的销售额是多少?→
GROUP BY month - 哪些产品的销量超过1000?→
HAVING SUM(quantity) > 1000
这些技能在写报表、做数据分析时几乎天天用。
👋 我是数据库小学妹,一个从设计转行数据库的菜鸟。我们一起,把复杂的技术变得简单有趣!💪
本文为个人学习总结,所有命令均在MySQL 8.0环境下验证。建议先用小数据量测试,理解清楚再应用到实际场景。