将NOT EXISTS的SQL转为LEFT JOIN后记录数不符,求正确转换写法
NOT EXISTS转LEFT JOIN的正确写法
你的原查询用NOT EXISTS筛选的是:主查询关联TABLE1/2/3后,不存在与TABLE4、TABLE5关联且满足aj.col <>5、rj.col=rpc.col的记录。
你写的LEFT JOIN版本有两个核心问题:
- TABLE4与TABLE5的关联条件写错(原逻辑是
rj.col=aj.col,你写成了rj.col1=aj.col) - 缺少关键过滤:LEFT JOIN后没有排除掉匹配到的记录,这是导致记录数不一致的根本原因
正确的LEFT JOIN写法(两种方式)
方式1:连续LEFT JOIN
select distinct rpc.col from TABLE1 rpc inner join TABLE2 rrp on rrp.col = rpc.col inner join TABLE3 pro on rrp.col = pro.col left join TABLE4 rj on rj.col = rpc.col left join TABLE5 aj on rj.col = aj.col and aj.col <> 5 where 1=1 and pro.col = 'TEXT' and rpc.col = 2 -- 过滤掉匹配到TABLE4/TABLE5的记录,对应原NOT EXISTS的逻辑 and rj.col is null
方式2:子查询封装关联逻辑
select distinct rpc.col from TABLE1 rpc inner join TABLE2 rrp on rrp.col = rpc.col inner join TABLE3 pro on rrp.col = pro.col left join ( -- 先把TABLE4和TABLE5的关联逻辑封装成子查询 select rj.col from TABLE4 rj inner join TABLE5 aj on rj.col = aj.col where aj.col <> 5 ) rj_aj on rj_aj.col = rpc.col where 1=1 and pro.col = 'TEXT' and rpc.col = 2 -- 同样过滤掉匹配到的记录 and rj_aj.col is null
关键说明
- 把
aj.col <>5放在LEFT JOIN的ON子句中,而不是WHERE子句:如果放在WHERE里,会把LEFT JOIN自动转换成INNER JOIN(因为NULL值与任何条件比较都会被过滤),破坏原逻辑。 - 通过
rj.col is null(或子查询字段为NULL)筛选出没有匹配到TABLE4/TABLE5关联记录的结果,完全对应原NOT EXISTS的语义。
内容的提问来源于stack exchange,提问作者Tex Chess
相关产品推荐
相关产品推荐

