SQL SELECT子查询求助:筛选无assignment 11成绩的学生姓名
嘿,我来帮你搞定这个筛选问题!单独跑SQL语句没问题,组合就失效,这种情况我碰到过好多次,大概率是关联逻辑或者子查询的写法踩坑了。
先假设你的表结构大概是这类常见的设计(如果和实际不符,你可以调整字段名就行):
students表:存学生信息,核心字段student_id(主键)、name(学生姓名)assignment_scores表:存作业成绩,核心字段student_id(关联students的外键)、assignment_name(作业名称,比如'Assignment 11')、score(成绩)
下面给你两种经过验证的靠谱写法,应该能解决你的组合失效问题:
方案1:LEFT JOIN + 空值筛选
这种写法用左连接保留所有学生,再过滤出没有Assignment 11成绩的记录:
SELECT s.name FROM students s LEFT JOIN assignment_scores sc ON s.student_id = sc.student_id AND sc.assignment_name = 'Assignment 11' WHERE sc.score IS NULL;
为啥这个能行? LEFT JOIN会把students里的所有学生都列出来,哪怕assignment_scores里没有对应Assignment 11的记录,这时候sc.score就会是NULL,我们只要筛选这些NULL的行就行。
方案2:NOT EXISTS 子查询
如果更习惯用子查询,这种写法逻辑更直观,直接找“不存在Assignment 11成绩记录”的学生:
SELECT s.name FROM students s WHERE NOT EXISTS ( SELECT 1 FROM assignment_scores sc WHERE sc.student_id = s.student_id AND sc.assignment_name = 'Assignment 11' -- 如果需要排除“提交了但没打分(score为NULL)”的情况,就保留下面这句;如果只要没成绩(不管有没有提交记录),就删掉 AND sc.score IS NOT NULL );
为啥这个靠谱? NOT EXISTS会逐个检查每个学生,只要子查询里找不到对应的Assignment 11成绩记录,就会把这个学生选出来,逻辑清晰不容易出错。
你之前组合失效可能踩的坑:
- 用了
INNER JOIN:内连接只会保留两边都有匹配的记录,直接把没成绩的学生过滤掉了 - 子查询里的关联条件写错:比如没把
students和assignment_scores的student_id关联起来,导致子查询跑出来的是全局没成绩的记录,不是针对每个学生的 - 作业名称匹配问题:比如大小写、空格不一样(比如你写的是'assignment 11'但库里是'Assignment 11'),导致匹配不到
你可以根据自己的实际表结构调整上面的SQL,应该就能得到想要的结果啦!
内容的提问来源于stack exchange,提问作者matrixfox
相关产品推荐
相关产品推荐

