将子查询转换为Window Function:基于首次选课日期找最受欢迎课程
使用窗口函数找出最受欢迎的学生首选课程
窗口函数实现代码
WITH StudentFirstChoice AS ( SELECT ClassID, ROW_NUMBER() OVER (PARTITION BY StudentID ORDER BY EnrollmentDT ASC) AS ChoiceRank FROM StudentClass ) SELECT ClassID, COUNT(*) AS IsFavoriteClassCount FROM StudentFirstChoice WHERE ChoiceRank = 1 GROUP BY ClassID ORDER BY IsFavoriteClassCount DESC;
逻辑说明
- 标记学生的首选课程:
使用ROW_NUMBER()窗口函数,按StudentID分组(PARTITION BY StudentID),对每个学生的选课记录按EnrollmentDT升序排序。由于题目明确无重复的选课日期,每个学生的首次选课会被分配排名1,后续选课排名依次递增。 - 筛选首选记录:
通过CTE创建临时数据集,仅保留ChoiceRank = 1的行,这些就是每个学生最开始选择的(即最喜欢的)课程。 - 统计课程受欢迎程度:
对筛选后的数据集按ClassID分组,统计每个课程被选为首选的次数,最后按次数降序排序,得到最受欢迎的课程排名。
与子查询解法的对比
你的子查询解法逻辑正确,但窗口函数实现有明显优势:
- 无需额外的表连接操作,查询逻辑更简洁直观,减少了多表关联带来的性能开销(尤其是数据量较大时)。
- 扩展性更强:如果后续需要统计学生前N个首选课程,只需调整
ChoiceRank的筛选条件(比如ChoiceRank <= 2),无需重构整个查询结构。 - 代码可读性更高:窗口函数的语义更贴近业务逻辑,一眼就能看出是在对每个学生的选课记录做排名筛选。
适配测试数据
该查询完全兼容你搭建的测试表结构,核心仅依赖StudentClass表中的StudentID、ClassID和EnrollmentDT字段,无需修改即可在你的测试环境中运行。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

