将NOT EXISTS查询转换为LEFT JOIN时结果不符的问题求助
将NOT EXISTS查询转换为LEFT JOIN时结果不符的问题求助
嗨,我来帮你梳理下问题出在哪儿~
首先得先把原NOT EXISTS查询的逻辑搞清楚:你要找的是不存在任何符合以下条件的T2记录的T1行:
- T2和当前T1关联(
T2.TOneId = T1.TOneId) - 并且要么
T2.Column是NULL,要么和T2关联的T3.Column是NULL
换句话说,原查询等价于:对于某条T1,所有和它关联的T2,都同时满足T2.Column IS NOT NULL,且对应的T3(通过T3.TTwoId=T2.TTwoId关联的)的T3.Column IS NOT NULL。
再看你写的LEFT JOIN查询,问题出在JOIN条件和WHERE条件的逻辑完全偏离了原需求:
你把T2.Column IS NULL和T3.Column IS NULL放到了JOIN的关联条件里,然后WHERE要求T2和T3的主键都为空——这其实是在找完全没有关联T2,或者即使有T2也不满足T2.Column IS NULL,同时也找不到满足T3.Column IS NULL的T3的T1行,这和原逻辑完全不是一回事。
正确的转换方式应该是先把符合原NOT EXISTS里子查询条件的记录(也就是那些T2+关联T3满足T2.Column IS NULL OR T3.Column IS NULL的组合)先筛选出来,再和T1做左连,最后判断这个关联结果不存在(也就是对应的T2主键为空)。
给你写个正确的版本:
SELECT T1.TOneID FROM TOne T1 LEFT JOIN ( -- 先找出所有符合原NOT EXISTS子查询条件的T2记录(包括关联的T3判断) SELECT DISTINCT T2.TOneId, T2.TTwoId FROM TTwo T2 LEFT JOIN TThree T3 ON T3.TTwoId = T2.TTwoId WHERE T2.Column IS NULL OR T3.Column IS NULL ) AS BadT2 ON BadT2.TOneId = T1.TOneId WHERE BadT2.TTwoId IS NULL -- 表示不存在这样的BadT2,也就是原NOT EXISTS的逻辑
或者也可以不用子查询,直接把T2和T3的关联+筛选条件放到LEFT JOIN里,然后判断关联后的T2主键为空:
SELECT T1.TOneID FROM TOne T1 LEFT JOIN TTwo T2 ON T2.TOneId = T1.TOneId AND ( T2.Column IS NULL OR EXISTS (SELECT 1 FROM TThree T3 WHERE T3.TTwoId = T2.TTwoId AND T3.Column IS NULL) ) WHERE T2.TTwoId IS NULL
这两种写法都能和原NOT EXISTS查询得到一致的结果,你可以试试~
备注:内容来源于stack exchange,提问作者NotFunWithBadCode
相关产品推荐
相关产品推荐

