You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何筛选仅选修单门课程的学生学号?窗口函数WHERE子句报错求助

解决SQL窗口函数不能在WHERE/HAVING中使用的问题及需求实现

原SQL的问题分析

  • 窗口函数(如count() over())的执行时机晚于WHERE子句,因此WHERE里无法直接引用窗口函数生成的别名values;HAVING子句需要配合GROUP BY使用,原SQL没有GROUP BY,所以用HAVING也无效。
  • 分组逻辑错误:你按拼接后的key(学号+课程)分区,统计的是每个学号+课程组合的出现次数,而不是每个学生的选修课程总数,这和“筛选仅选修一门课程的学生”的需求不匹配。

正确实现方案

方案一:用GROUP BY + HAVING直接筛选学号

如果只需要获取符合条件的学生学号,这是最简洁的写法:

SELECT roll_number
FROM subject_data
WHERE roll_number IS NOT NULL AND subject IS NOT NULL
GROUP BY roll_number
HAVING COUNT(subject) = 1;
  • 说明:按学号分组,统计每个学生的选修课程数量;如果同一个学生可能重复选同一门课,需要用COUNT(DISTINCT subject)去重后统计。

方案二:用子查询/CTE结合窗口函数(需保留课程信息时使用)

如果需要同时保留学生的课程信息,可以先通过子查询或CTE计算每个学生的课程总数,再在外层筛选:

-- 用CTE写法
WITH student_course_stats AS (
    SELECT
        roll_number,
        subject,
        COUNT(subject) OVER(PARTITION BY roll_number) AS total_courses
    FROM subject_data
    WHERE roll_number IS NOT NULL AND subject IS NOT NULL
)
SELECT roll_number, subject
FROM student_course_stats
WHERE total_courses = 1;

-- 或者子查询写法
SELECT roll_number, subject
FROM (
    SELECT
        roll_number,
        subject,
        COUNT(subject) OVER(PARTITION BY roll_number) AS total_courses
    FROM subject_data
    WHERE roll_number IS NOT NULL AND subject IS NOT NULL
) AS temp
WHERE total_courses = 1;
  • 说明:先通过窗口函数按学号分区,计算每个学生的总课程数,再在外层WHERE中筛选总课程数为1的记录。

内容的提问来源于stack exchange,提问作者Farzam Ashhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 05:12:08