怎样做医院网站,wordpress post 属性,猎头公司的原则是,广告公司简介怎么写大气SQL从0到1#xff1a;汇总、分组与排序实战
在日常的数据分析工作中#xff0c;我们常常需要回答诸如“每门课的平均成绩是多少#xff1f;”、“哪些学生挂科了#xff1f;”、“哪个班级人数最多#xff1f;”这样的问题。这些问题看似简单#xff0c;但背后其实都依赖…SQL从0到1汇总、分组与排序实战在日常的数据分析工作中我们常常需要回答诸如“每门课的平均成绩是多少”、“哪些学生挂科了”、“哪个班级人数最多”这样的问题。这些问题看似简单但背后其实都依赖于SQL中几个核心能力汇总统计、分组聚合、条件筛选和结果排序。掌握这些技能你就能把一堆原始数据变成真正有价值的洞察。而这一切并不需要复杂的编程技巧只需要理解清楚SQL的逻辑脉络——尤其是它的执行顺序和语法边界。汇总分析用一个值看懂一组数据当你面对成百上千条记录时最直接的需求往往是“总体情况如何”。这时候就要靠汇总函数Aggregate Functions出马了。常见的几个函数就像数据分析的“基本功”COUNT()统计非空值的数量常用来算人数、记录数SUM()对数值求和比如总销售额、总学分AVG()计算平均值注意它会自动忽略NULLMAX()/MIN()找极值适用于数字、日期甚至字符串举个例子想看看教师表里有多少位老师可以这样写SELECT COUNT(教师姓名) FROM teacher;但如果某些老师的姓名是空的呢为了确保每一行都被计入更稳妥的做法是使用COUNT(*)它不关心字段内容是否为空SELECT COUNT(*) FROM teacher;再比如想知道所有学生的平均成绩SELECT AVG(成绩) FROM score;这里有个细节如果某条成绩为 NULL它不会参与计算。也就是说AVG只基于实际存在的数值进行运算。还有一个实用技巧——去重统计。假设你想知道有多少不同的学生选过课而不是总共多少条选课记录SELECT COUNT(DISTINCT 学号) AS 学生总数 FROM score;这个DISTINCT很关键少了它重复出现的学号会被多次计数。✅ 小贴士SUM和AVG只能用于数值类型COUNT则不受限制任何字段都能用。分组按维度拆解数据光有整体统计还不够。业务上更多时候需要“分门别类地看”。比如“男生和女生各有多少人”、“每门课的最高分是多少”这就需要用到GROUP BY。它的作用是将数据按照某一列或多列的值进行划分然后在每个组内独立执行聚合操作。例如统计不同性别的学生人数SELECT 性别, COUNT(*) AS 人数 FROM student GROUP BY 性别;这条语句的执行流程大致如下1. 从student表读取数据FROM2. 先过滤出生日期晚于1990年的学生WHERE3. 按性别分组GROUP BY4. 在每组中统计行数COUNT5. 最后返回结果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第三步写SQLSELECT 课程号, 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 → LIMITWHERE发生在SELECT之前那时avg_score还没被定义当然找不到。✅ 正确做法是改用HAVINGSELECT 课程号, 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 表示是 NULL0 表示非 NULL。由于默认升序0 在前、1 在后因此非空值优先显示。2. 自定义分类排序有时候我们需要打破字母或数字顺序比如希望“语文”排第一“数学”第二。可以通过布尔表达式实现SELECT 课程号, AVG(成绩) FROM score GROUP BY 课程号 ORDER BY (课程号 0001) DESC; -- 0001为语文匹配时返回1DESC使其靠前更灵活的方式是使用CASE WHENORDER 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 ONeillSUM and COUNT 进阶任务尝试完成1. 统计每年诺贝尔奖的颁发次数2. 找出获得过多次奖项的国家3. 查询“和平奖”颁发次数最多的十年区间这些题目会让你反复运用GROUP BY、HAVING和ORDER BY帮助你形成肌肉记忆。写在最后构建你的SQL思维框架到现在为止你应该已经掌握了SQL中最常用的四大操作操作关键词用途汇总COUNT,SUM,AVG,MAX,MIN数据统计分组GROUP BY按维度分类聚合分组过滤HAVING筛选满足条件的组排序ORDER BYLIMIT控制输出顺序与数量更重要的是你了解了SQL的执行顺序这一底层逻辑。这是区分“照着抄代码”和“真正理解”的关键所在。下一步你可以继续学习- 多表连接JOIN- 子查询- 窗口函数Window Functions但请记住基础决定上限。能把简单的查询写对、写清、写高效的人往往比只会炫技的人更能解决实际问题。坚持动手实践把每一个知识点都变成你自己的工具箱里的一把趁手好刀。当你能自信地说“这个问题我可以用SQL搞定”时你就真的入门了。