如何仅对表子集应用内连接?优化重复检查字段的SQL查询
优化后的SQL实现
需求回顾
获取所有学生姓名,但男生仅保留成绩及格(分数>70)的学生,最终返回符合条件的学生名单。
优化方案1:使用EXISTS子查询
这种方式逻辑清晰,仅需一次性别判断,分数筛选仅在子查询中执行一次:
SELECT s.name FROM Students s WHERE s.Gender != 'M' OR EXISTS ( SELECT 1 FROM Scores sc WHERE sc.StudentID = s.ID AND sc.Score > 70 )
逻辑说明
- 女生(
s.Gender != 'M')直接保留,无需关联成绩表 - 男生通过
EXISTS子查询判断是否存在至少一次及格成绩,存在则保留
优化方案2:简化LEFT JOIN写法
同样仅需一次性别判断,分数筛选在JOIN条件中执行一次,配合DISTINCT避免重复记录:
SELECT DISTINCT s.name FROM Students s LEFT JOIN Scores sc ON sc.StudentID = s.ID AND sc.Score > 70 WHERE s.Gender != 'M' OR sc.StudentID IS NOT NULL
逻辑说明
- 先通过LEFT JOIN关联所有学生与他们的及格成绩记录
- WHERE条件中:女生直接保留;男生仅保留有匹配及格成绩的记录(
sc.StudentID IS NOT NULL) DISTINCT用于避免同一男生有多条及格成绩时出现重复姓名
对比原语句的优势
原语句在JOIN条件和WHERE条件中重复检查gender字段共3次,上述两种优化方案仅需1次性别判断,分数筛选也仅执行1次,既简化了代码逻辑,也减少了数据库的字段检查次数。
内容的提问来源于stack exchange,提问作者user18738617
相关产品推荐
相关产品推荐

