news 2026/3/20 8:26:03

SQL从0到1:汇总、分组与排序实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL从0到1:汇总、分组与排序实战

SQL从0到1:汇总、分组与排序实战

在日常的数据分析工作中,我们常常需要回答诸如“每门课的平均成绩是多少?”、“哪些学生挂科了?”、“哪个班级人数最多?”这样的问题。这些问题看似简单,但背后其实都依赖于SQL中几个核心能力:汇总统计、分组聚合、条件筛选和结果排序

掌握这些技能,你就能把一堆原始数据变成真正有价值的洞察。而这一切,并不需要复杂的编程技巧,只需要理解清楚SQL的逻辑脉络——尤其是它的执行顺序和语法边界。


汇总分析:用一个值看懂一组数据

当你面对成百上千条记录时,最直接的需求往往是“总体情况如何”。这时候就要靠汇总函数(Aggregate Functions)出马了。

常见的几个函数就像数据分析的“基本功”:

  • COUNT():统计非空值的数量,常用来算人数、记录数
  • SUM():对数值求和,比如总销售额、总学分
  • AVG():计算平均值,注意它会自动忽略NULL
  • MAX()/MIN():找极值,适用于数字、日期甚至字符串

举个例子,想看看教师表里有多少位老师?可以这样写:

SELECT COUNT(教师姓名) FROM teacher;

但如果某些老师的姓名是空的呢?为了确保每一行都被计入,更稳妥的做法是使用COUNT(*),它不关心字段内容是否为空:

SELECT COUNT(*) FROM teacher;

再比如,想知道所有学生的平均成绩:

SELECT AVG(成绩) FROM score;

这里有个细节:如果某条成绩为 NULL,它不会参与计算。也就是说,AVG只基于实际存在的数值进行运算。

还有一个实用技巧——去重统计。假设你想知道有多少不同的学生选过课,而不是总共多少条选课记录:

SELECT COUNT(DISTINCT 学号) AS 学生总数 FROM score;

这个DISTINCT很关键,少了它,重复出现的学号会被多次计数。

✅ 小贴士:SUMAVG只能用于数值类型;COUNT则不受限制,任何字段都能用。


分组:按维度拆解数据

光有整体统计还不够。业务上更多时候需要“分门别类地看”。比如:“男生和女生各有多少人?”、“每门课的最高分是多少?”

这就需要用到GROUP BY

它的作用是将数据按照某一列或多列的值进行划分,然后在每个组内独立执行聚合操作。

例如,统计不同性别的学生人数:

SELECT 性别, COUNT(*) AS 人数 FROM student GROUP BY 性别;

这条语句的执行流程大致如下:
1. 从student表读取数据(FROM)
2. 先过滤出生日期晚于1990年的学生(WHERE)
3. 按性别分组(GROUP BY)
4. 在每组中统计行数(COUNT)
5. 最后返回结果(SELECT)

所以你会发现,出现在 SELECT 中的非聚合字段(如“性别”),必须也出现在 GROUP BY 中,否则数据库不知道该选哪个值输出。

再来看一个典型场景:查询每门课程的最高分和最低分:

SELECT 课程号, MAX(成绩), MIN(成绩) FROM score GROUP BY 课程号;

这条查询清晰地告诉我们每门课的成绩分布范围,对于教学质量评估非常有用。


对分组结果做筛选:HAVING 的正确打开方式

很多人初学时容易犯一个错误:想筛选“平均成绩大于60的学生”,于是这么写:

-- ❌ 错误示例 SELECT 学号, AVG(成绩) FROM score WHERE AVG(成绩) > 60 GROUP BY 学号;

结果报错。为什么?

因为WHERE是在分组前对原始行进行过滤的,而AVG(成绩)是分组后才产生的聚合结果,此时还不存在,自然无法使用。

正确的做法是使用HAVING

-- ✅ 正确写法 SELECT 学号, AVG(成绩) AS 平均成绩 FROM score GROUP BY 学号 HAVING AVG(成绩) > 60;

HAVING就是用来过滤“分组之后的结果”的,它可以安全地使用聚合函数作为判断条件。

另一个常见需求是找出至少选修了两门课的学生:

SELECT 学号, COUNT(课程号) AS 选修课程数 FROM score GROUP BY 学号 HAVING COUNT(课程号) >= 2;

或者查找有没有同名同姓的学生:

SELECT 姓名, COUNT(*) AS 人数 FROM student GROUP BY 姓名 HAVING COUNT(*) > 1;

你会发现,这类问题本质上都是“先分组,再看组的特征”,而这正是HAVING的主场。


如何把业务问题翻译成SQL?

现实中没人会直接告诉你“请写一条带 HAVING 的 GROUP BY 查询”。你需要自己把自然语言转化成技术逻辑。

推荐一个三步法:

第一步:说人话

把问题用自己的话重新表述一遍。
比如:“找出平均成绩不低于80分的课程” → “先把成绩按课程分组,算出每组平均分,然后只保留那些平均分≥80的课程”。

第二步:理思路

明确以下几点:
- 用哪张表?→score
- 要查什么?→ 课程号 + 平均成绩
- 是否需要分组?→ 是,按课程号
- 是否需要聚合?→ 是,用 AVG
- 是否需要筛选分组结果?→ 是,用 HAVING

第三步:写SQL
SELECT 课程号, AVG(成绩) AS 平均成绩 FROM score GROUP BY 课程号 HAVING AVG(成绩) >= 80;

整个过程就像搭积木,每一步都有据可依,避免盲目试错。


排序输出:让结果更有意义

即使数据准确无误,如果杂乱无章地展示,用户仍然难以快速获取信息。这时就需要ORDER BY来控制显示顺序。

默认是升序(ASC),可以用 DESC 改为降序:

-- 按成绩从高到低排列 SELECT * FROM score ORDER BY 成绩 DESC;

支持多级排序。比如成绩相同时,希望课程号大的排前面:

SELECT * FROM score ORDER BY 成绩 DESC, 课程号 DESC;

结合LIMIT还能轻松实现“取Top N”的需求:

-- 查看前两名最高分 SELECT * FROM score ORDER BY 成绩 DESC LIMIT 2;

这在排行榜、绩效排名等场景中极为常用。

不过要注意的是,排序是在 SELECT 之后才发生的,所以你可以对别名进行排序:

SELECT 课程号, AVG(成绩) AS 平均成绩 FROM score GROUP BY 课程号 ORDER BY 平均成绩 DESC;

这里的平均成绩是别名,在 ORDER BY 中可用,但在 WHERE 或 HAVING 中不能直接使用(除非重写表达式)。


常见错误解析:看懂报错信息才能少走弯路

写SQL最大的挫败感之一就是:明明逻辑很通顺,却一直报错。其实很多错误都有固定模式,学会解读就能事半功倍。

错误1:在 WHERE 中使用别名
-- ❌ 报错! SELECT 课程号, AVG(成绩) AS avg_score FROM score WHERE avg_score >= 80 GROUP BY 课程号;

为什么会错?因为 SQL 的执行顺序是:

FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

WHERE发生在SELECT之前,那时avg_score还没被定义,当然找不到。

✅ 正确做法是改用HAVING

SELECT 课程号, AVG(成绩) AS avg_score FROM score GROUP BY 课程号 HAVING AVG(成绩) >= 80;
错误2:在 WHERE 中使用聚合函数
-- ❌ 报错! SELECT 性别, COUNT(*) FROM student WHERE COUNT(*) > 1 GROUP BY 性别;

COUNT(*)是对一组数据的操作,而WHERE面向的是单行数据,两者不在同一阶段。

✅ 应该用HAVING替代:

SELECT 性别, COUNT(*) AS 人数 FROM student GROUP BY 性别 HAVING COUNT(*) > 1;

📌 核心原则再次强调:
-WHERE:过滤原始行(分组前)
-HAVING:过滤分组后的组(分组后)


进阶技巧:处理 NULL 与自定义排序

1. NULL 值在排序中的位置

大多数数据库系统中,NULL在升序排序时被视为“最小值”,通常排在最前面。

比如:

SELECT * FROM teacher ORDER BY 教师姓名;

如果有老师姓名为空,他们就会出现在列表开头,可能不符合预期。

想要让NULL排在最后,可以在 MySQL 中利用ISNULL()COALESCE()

-- MySQL 下将 NULL 排到最后 SELECT * FROM teacher ORDER BY ISNULL(教师姓名), 教师姓名;

原理是:ISNULL(教师姓名)返回 1 表示是 NULL,0 表示非 NULL。由于默认升序,0 在前、1 在后,因此非空值优先显示。

2. 自定义分类排序

有时候我们需要打破字母或数字顺序,比如希望“语文”排第一,“数学”第二。

可以通过布尔表达式实现:

SELECT 课程号, AVG(成绩) FROM score GROUP BY 课程号 ORDER BY (课程号 = '0001') DESC; -- '0001'为语文,匹配时返回1,DESC使其靠前

更灵活的方式是使用CASE WHEN

ORDER BY CASE 课程号 WHEN '0001' THEN 1 -- 语文 WHEN '0002' THEN 2 -- 数学 ELSE 3 END;

这种方式扩展性强,适合复杂排序逻辑。


动手练习:巩固所学的最佳方式

理论懂了不算真会,只有亲手敲出来才算掌握。

推荐前往 SQLZOO 完成以下模块练习:

SELECT from Nobel
  • 查询获奖者名为'Martin Luther King'的记录:
SELECT * FROM nobel WHERE winner = 'Martin Luther King';
  • 如果名字含单引号(如 O’Neill),需用两个单引号转义:
WHERE winner = 'O''Neill'
SUM and COUNT 进阶任务

尝试完成:
1. 统计每年诺贝尔奖的颁发次数
2. 找出获得过多次奖项的国家
3. 查询“和平奖”颁发次数最多的十年区间

这些题目会让你反复运用GROUP BYHAVINGORDER BY,帮助你形成肌肉记忆。


写在最后:构建你的SQL思维框架

到现在为止,你应该已经掌握了SQL中最常用的四大操作:

操作关键词用途
汇总COUNT,SUM,AVG,MAX,MIN数据统计
分组GROUP BY按维度分类聚合
分组过滤HAVING筛选满足条件的组
排序ORDER BY+LIMIT控制输出顺序与数量

更重要的是,你了解了SQL的执行顺序这一底层逻辑。这是区分“照着抄代码”和“真正理解”的关键所在。

下一步,你可以继续学习:
- 多表连接(JOIN)
- 子查询
- 窗口函数(Window Functions)

但请记住:基础决定上限。能把简单的查询写对、写清、写高效的人,往往比只会炫技的人更能解决实际问题。

坚持动手实践,把每一个知识点都变成你自己的工具箱里的一把趁手好刀。当你能自信地说“这个问题我可以用SQL搞定”时,你就真的入门了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/16 3:49:21

熔融缩聚动力学:聚酯反应速率常数测定

Z-Image-ComfyUI 图像生成系统的动态性能分析 在当前AIGC技术飞速发展的背景下,图像生成模型早已不再局限于“能否画出一张好看图片”的初级阶段。真正的挑战在于:如何让高质量生成变得足够快、足够稳、足够可控?这不仅是用户体验的问题&…

作者头像 李华
网站建设 2026/3/15 18:52:41

Crazyflie2 NRF固件hex文件分析

Crazyflie2 NRF固件hex文件分析 在嵌入式系统的世界里,一个看似杂乱的文本文件,可能就是整个设备的灵魂。当你打开Crazyflie 2.0无人机NRF51822芯片的固件HEX文件时,看到的是一串以:开头的数据行: :1060000000400020ADEC0100E9E…

作者头像 李华
网站建设 2026/3/16 3:49:22

Open-AutoGLM手机端安装实战(从零到一键操控的完整流程)

第一章:Open-AutoGLM手机端安装实战概述Open-AutoGLM 是一款基于 AutoGLM 架构的开源移动端应用,专为在 Android 设备上实现本地化大语言模型推理而设计。其核心优势在于支持离线运行、低资源消耗以及与主流 AI 框架的兼容性,适合开发者在移动…

作者头像 李华
网站建设 2026/3/16 3:49:21

【cogagent与Open-AutoGLM深度对比】:揭秘两大AI框架核心差异与选型指南

第一章:cogagent与Open-AutoGLM选型背景与趋势随着大模型技术在自动化机器学习(AutoML)领域的深入应用,选择具备高效推理能力与任务理解能力的智能代理框架成为关键。cogagent 与 Open-AutoGLM 作为当前主流的两类开源智能代理系统…

作者头像 李华
网站建设 2026/3/16 3:49:26

光栅衍射主极大个数与大学物理光学解析

光栅衍射主极大个数与大学物理光学解析 在光学实验中,我们常会观察到这样的现象:一束光穿过刻有密集狭缝的光栅后,在远处屏幕上形成一系列明暗相间的条纹。这些明亮的“主极大”并非均匀分布,有些级次甚至完全消失不见——这背后正…

作者头像 李华
网站建设 2026/3/19 18:17:15

CI/CD工具一文纵评,Tekton vs Jenkins vs Arbess

面对众多的CI/CD工具,如何根据功能、价格和易用性做出选择?本文旨在通过多款工具的横向对比,为你提供清晰的梳理与参考。1、Tekton1.1 产品介绍Tekton 是由 ‌Google 开源‌的云原生 CI/CD 工具,通过K8S云平台快速灵活定义流水线&…

作者头像 李华