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

MySQL查询问题:如何筛选仅2015年选课的学生

解决仅筛选2015年选课学生的SQL问题

嘿,我来帮你搞定这个SQL筛选的问题!你的核心需求是找出只在2015年选过课、完全没选过2016年课程的学生,而当前SQL语句之所以会包含跨年度选课的学生,是因为e.subjectCode NOT LIKE '_______16__'是对单条选课记录做过滤——只要学生有一门2015年的课,这条记录就会被选中,哪怕他同时选了2016年的课,最终分组后自然会把他包含进来。

下面给你几个靠谱的解决方案:

方法1:用NOT EXISTS子查询(最直观)

这种方法直接检查学生是否存在2016年的选课记录,同时确保他确实选过2015年的课:

SELECT s.firstName, d.degreeCode
FROM students s
JOIN degrees d ON s.studentID = d.studentID
WHERE NOT EXISTS (
    -- 检查该学生是否有2016年的选课记录
    SELECT 1
    FROM enrolled e
    WHERE e.studentID = s.studentID
    AND e.subjectCode LIKE '_______16__'
)
AND EXISTS (
    -- 确保该学生确实选过2015年的课,避免无选课记录的学生被误选
    SELECT 1
    FROM enrolled e
    WHERE e.studentID = s.studentID
    AND e.subjectCode LIKE '_______15__'
)
GROUP BY s.studentID, s.firstName, d.degreeCode;

注:GROUP BY里加上s.studentID是为了避免重名学生被合并,不同数据库对GROUP BY的严格性要求不同,加上主键更稳妥。

方法2:用GROUP BY + HAVING统计选课年份

通过统计学生的选课记录中2016年课程的数量,确保数量为0,同时2015年课程数量大于0:

SELECT s.firstName, d.degreeCode
FROM students s
JOIN degrees d ON s.studentID = d.studentID
JOIN enrolled e ON s.studentID = e.studentID
GROUP BY s.studentID, s.firstName, d.degreeCode
HAVING 
    -- 2016年选课数为0
    SUM(CASE WHEN e.subjectCode LIKE '_______16__' THEN 1 ELSE 0 END) = 0
    -- 2015年选课数至少为1
    AND SUM(CASE WHEN e.subjectCode LIKE '_______15__' THEN 1 ELSE 0 END) > 0;

方法3:用LEFT JOIN排除法

通过左连接2016年的选课记录,筛选出没有匹配到2016记录的学生:

SELECT DISTINCT s.firstName, d.degreeCode
FROM students s
JOIN degrees d ON s.studentID = d.studentID
JOIN enrolled e1 ON s.studentID = e1.studentID
LEFT JOIN enrolled e2 ON s.studentID = e2.studentID AND e2.subjectCode LIKE '_______16__'
WHERE 
    e1.subjectCode LIKE '_______15__'
    -- 没有匹配到2016年的选课记录
    AND e2.studentID IS NULL;

注:用DISTINCT是因为一个学生可能有多门2015年的课,避免结果重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:38:31