SQL如何对比两表行数据查找未录入期末成绩的学生记录
SQL实现方案
匹配逻辑说明
学生成绩记录的唯一维度是STUDENT_NAME(学生姓名)+ GPA_YEAR(学年),单靠学生姓名匹配会混淆同一学生不同学年的录入状态,必须同时用两个字段做关联匹配,才能精准定位未录入成绩的记录。
未录入FINAL_GRADES包含两种场景:
- FINAL_GPA表中完全不存在该学生对应学年的记录
- FINAL_GPA表中存在该学生对应学年的记录,但FINAL_GRADES字段值为空
方案1:LEFT JOIN 写法(全数据库兼容)
所有关系型数据库都支持该写法,适配性最强:
SELECT s.STUDENT_NAME, s.GPA_YEAR FROM student s LEFT JOIN FINAL_GPA g ON s.STUDENT_NAME = g.STUDENT_NAME AND s.GPA_YEAR = g.GPA_YEAR WHERE g.FINAL_GRADES IS NULL;
逻辑说明:左连接会保留student表的全部学生学年记录,匹配不到同姓名同学年的FINAL_GPA记录时,关联后的g表字段全部为NULL,会被WHERE条件命中;如果存在对应记录但FINAL_GRADES未填(值为NULL),同样会被筛选出来,覆盖所有漏录场景。
方案2:NOT EXISTS 写法(大表性能更优)
如果两张表数据量较大,且FINAL_GPA表已创建(STUDENT_NAME, GPA_YEAR)联合索引,该写法执行效率更高:
SELECT s.STUDENT_NAME, s.GPA_YEAR FROM student s WHERE NOT EXISTS ( SELECT 1 FROM FINAL_GPA g WHERE g.STUDENT_NAME = s.STUDENT_NAME AND g.GPA_YEAR = s.GPA_YEAR AND g.FINAL_GRADES IS NOT NULL );
注意事项
- 禁止仅用STUDENT_NAME作为两表关联条件,否则会出现「学生某学年已录入成绩、其他学年未录入被误判为已录入」的错误。
- 如果业务规则明确:未录入成绩的记录不会提前插入FINAL_GPA表(即不存在「有记录但成绩为空」的情况),可以去掉上述SQL中对FINAL_GRADES字段的非空判断,简化查询逻辑。
内容的提问来源于stack exchange,提问作者GeogeTheCookie
相关产品推荐
相关产品推荐

