如何使用UNION/INTERSECTION查询modules表中数据异常的记录?
排查modules表中无效的(userid, courseid)组合
以下几种方法都可以找出modules表中(userid, courseid)组合在courses表中不存在的记录,适配不同SQL场景:
方法1:NOT EXISTS子查询(推荐,性能稳定)
这是最常用且性能表现较好的方案,直接校验当前模块的组合是否无匹配的课程记录:
SELECT m.id, m.name, m.userid, m.courseid FROM modules m WHERE NOT EXISTS ( SELECT 1 FROM courses c WHERE c.userid = m.userid AND c.id = m.courseid );
核心逻辑:子查询检查courses表中是否存在对应userid和courseid(注意courses的主键是id,对应modules的courseid外键)的记录,NOT EXISTS会筛选出完全无匹配的modules行。
方法2:LEFT JOIN + IS NULL
通过左连接保留所有modules记录,筛选连接失败的无效行:
SELECT m.id, m.name, m.userid, m.courseid FROM modules m LEFT JOIN courses c ON c.userid = m.userid AND c.id = m.courseid WHERE c.id IS NULL;
核心逻辑:左连接会保留modules的所有条目,当courses中没有对应(userid, id)组合时,courses表的字段会是NULL,以此定位损坏数据。
方法3:NOT IN(需注意NULL值风险)
如果确认courses表中userid和id字段无NULL值,可以用这种简洁写法:
SELECT m.id, m.name, m.userid, m.courseid FROM modules m WHERE (m.userid, m.courseid) NOT IN ( SELECT c.userid, c.id FROM courses c );
核心逻辑:先提取courses中所有有效的(userid, id)组合集合,再筛选modules中不在该集合内的记录。注意:如果courses的子查询结果中存在NULL值,NOT IN会返回空结果,所以仅在数据无NULL时使用。
内容的提问来源于stack exchange,提问作者George Ji
相关产品推荐
相关产品推荐

