596. 超过5名学生的课
596. 超过5名学生的课
难度:简单 | 题号:596 | 链接:596. 超过 5 名学生的课 - 力扣(LeetCode) | 数据结构:SQL
关联:订单最多的用户(同为「分组计数 + 过滤」)· 查询近30天活跃用户数(分组去重计数)· 可对照 SQL原理_02(
GROUP BY/HAVING/WHERE与HAVING的区别)。
🎯 问题描述
描述:查询至少有 5 名学生的所有课程(班级)。结果以任意顺序返回。
表:Courses
1 | +-------------+---------+ |
示例 1:
1 | 输入: |
提示:
- 先按
class分组计数,再对分组结果过滤 → 必须用HAVING,不能用WHERE(WHERE在分组之前过滤行,看不到COUNT)。 - 题目提示「同一学生在同一课程中不应被重复计算」→ 本表
(student, class)是联合主键天然去重,COUNT(*)即可;但写COUNT(DISTINCT student)更防御(防止数据重复时误算)。 HAVING中不能引用列别名(HAVING cnt >= 5会报Unknown column),要写完整聚合表达式COUNT(*) >= 5。
💻 解题思路
思路1:GROUP BY + HAVING(用户解法)
核心逻辑
按 class 分组,COUNT(*) 数出每门课的学生数,HAVING COUNT(*) >= 5 筛出人数达标的课程。
代码实现
1 | # Write your MySQL query statement below |
💡 更防御的写法(同一学生重复选课时也正确):
1
2
3
4 SELECT class
FROM Courses
GROUP BY class
HAVING COUNT(DISTINCT student) >= 5;
📊 性能分析
- 时间复杂度:(全表扫描 + 哈希分组;
class上有索引可加速分组)。 - 空间复杂度:, 为课程数。
思考
WHEREvsHAVING—— 本题最核心的考点:WHERE作用于原始行,在GROUP BY之前执行,用不了聚合函数;HAVING作用于分组后的结果,在GROUP BY之后执行,专门用来筛选聚合值。- 口诀:「行级条件走 WHERE,组级条件走 HAVING」。
- 别把
student_count当别名用在HAVING里:SELECT class, COUNT(*) AS cnt ... HAVING cnt >= 5在 MySQL 里会报Error 1054: Unknown column 'cnt' in 'having clause'(HAVING的求值早于SELECT别名解析)→ 必须重写COUNT(*)。 COUNT(*)还是COUNT(DISTINCT student):依赖联合主键去重时二者等价;若表可能存在重复插入了同一(student, class),只有DISTINCT版才正确。工程里宁可多写DISTINCT。
🔗 相关链接
- 所属 MOC:学习-数据结构与算法MOC
- 题集索引:LeetCode题集索引
- 关联概念:SQL原理_02(分组过滤 / WHERE 与 HAVING)
- 同类题目:订单最多的用户(HAVING 计数)· 查询近30天活跃用户数(
COUNT(DISTINCT ...))
📝 总结
「分组后按计数过滤」模板:
GROUP BY 分组列 HAVING COUNT(...) >= N,一句话即得。- 三个关键点:① 组级条件用
HAVING,别用WHERE;②HAVING里不能引别名,写全COUNT(*);③ 人数类统计优先COUNT(DISTINCT 学生)防重复数据。
🔗 题集索引:LeetCode题集索引 · 算法地图:学习-数据结构与算法MOC
📎 同类题:订单最多的用户 · 查询近30天活跃用户数 | 概念:SQL原理_02
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






