查询未选修Jay教授任何课程的学生 现有SQL结果异常排查
问题根因
你原有查询的逻辑是行级过滤,只要学生有任意一门选课不属于Jay教授的课程,对应记录就会被命中返回,完全不符合「学生所有选课都不涉及Jay教授课程」的需求。你需要的是按学生维度做全局判断,而非单条选课记录的判断。
另外不建议硬编码course_id = "c001",如果后续Jay教授新增其他授课课程,硬编码的语句需要同步修改,鲁棒性较差。
正确查询方案
方案1:NOT EXISTS(最直观,性能最优)
逻辑:筛选出不存在「该学生选了Jay教授课程」记录的学生
SELECT s.* FROM Student s WHERE NOT EXISTS ( SELECT 1 FROM Enroll e JOIN Course c ON e.course_id = c.course_id JOIN Lecturer l ON c.lecturer_id = l.lecturer_id WHERE e.student_id = s.student_id AND l.name = 'Jay' );
如果确认Jay教授的课程只有c001,可以简化子查询内的关联逻辑,直接判断e.course_id = 'c001'即可。
方案2:先取选过Jay课程的学生ID再取反
SELECT * FROM Student WHERE student_id NOT IN ( SELECT DISTINCT e.student_id FROM Enroll e JOIN Course c ON e.course_id = c.course_id JOIN Lecturer l ON c.lecturer_id = l.lecturer_id WHERE l.name = 'Jay' );
注意:如果Enroll表的student_id字段允许为NULL,不要使用该方案,NULL值会导致NOT IN逻辑失效,优先选择NOT EXISTS方案。
方案3:分组聚合判断
SELECT s.student_id, s.name FROM Student s JOIN Enroll e ON s.student_id = e.student_id JOIN Course c ON e.course_id = c.course_id JOIN Lecturer l ON c.lecturer_id = l.lecturer_id GROUP BY s.student_id, s.name HAVING SUM(CASE WHEN l.name = 'Jay' THEN 1 ELSE 0 END) = 0;
验证结果
按照你提供的测试数据,以上三个查询均会返回空结果,符合预期。
内容的提问来源于stack exchange,提问作者Afiq Rosli
相关产品推荐
相关产品推荐

