如何筛选所有课程获F/W或未获成绩的学生?SQL优化求助
正确SQL写法及问题分析
需求拆解
需要筛选两类学生:
- 有至少一门课程成绩为
F或W的学生; - 在
202208、202302、202305学期有选课记录但未获得成绩的学生。
原SQL的核心问题
EXISTS子句未关联外部表的spriden_pidm,导致只要系统中存在任何学生有F/W成绩,所有符合spriden和rrrareq条件的学生都会被错误选中;LEFT JOIN shrtckg后添加shrtckg_term_code过滤条件,等价于将左连接转为内连接,丢失了无选课记录的学生;- 未处理“指定学期未获得成绩”的筛选逻辑。
修正后的SQL
SELECT DISTINCT spriden_id, spriden_first_name, spriden_last_name FROM spriden INNER JOIN rrrareq ON rrrareq_pidm = spriden_pidm AND rrrareq_treq_code = 'UEH359' AND rrrareq_trst_code = 'E' AND rrrareq_aidy_code = 2324 WHERE spriden_change_ind IS NULL AND ( -- 筛选有F/W成绩的学生 EXISTS ( SELECT 1 FROM shrtckg s1 WHERE s1.shrtckg_pidm = spriden_pidm AND s1.shrtckg_grde_code_final IN ('F', 'W') ) OR -- 筛选指定学期有选课但无成绩的学生 EXISTS ( SELECT 1 FROM shrtckg s2 WHERE s2.shrtckg_pidm = spriden_pidm AND s2.shrtckg_term_code IN ('202208', '202302', '202305') AND s2.shrtckg_grde_code_final IS NULL ) )
关键修改说明
- 每个
EXISTS子句都通过shrtckg_pidm = spriden_pidm关联当前学生,确保判断逻辑针对个体; - 用
OR连接两个独立条件,同时覆盖两类目标学生; - 移除原SQL中错误的左连接及后续过滤,避免丢失符合条件的学生;
- 保留
DISTINCT避免重复返回同一学生,同时保留原有的spriden_change_ind IS NULL过滤规则。
补充说明
如果需求中的“未获得成绩”包含指定学期完全没有选课记录的学生,可将第二个EXISTS改为NOT EXISTS,判断该学生在指定学期无任何选课记录:
-- 替换第二个条件为:指定学期无选课记录的学生 NOT EXISTS ( SELECT 1 FROM shrtckg s2 WHERE s2.shrtckg_pidm = spriden_pidm AND s2.shrtckg_term_code IN ('202208', '202302', '202305') )
内容的提问来源于stack exchange,提问作者Zyngle
相关产品推荐
相关产品推荐

