T-SQL中NOT IN含多SELECT语句报错,求替代实现方法
解决T-SQL中NOT IN包含多子查询的问题
嗨,这个问题我之前也碰到过!你原来的写法出错是因为T-SQL里NOT IN的括号里只能放单个返回单列的结果集,不能用OR直接连接多个SELECT语句。给你两种靠谱的解决方法:
方法1:用UNION ALL合并子查询
把多个子查询的结果合并成一个集合,再放到NOT IN里就行。推荐用UNION ALL,因为它不会做去重操作,性能比UNION(会自动去重)更好:
SELECT * FROM table1 WHERE ParamID NOT IN ( -- 合并多个表的ParamID结果 SELECT ParamID FROM tbl2 UNION ALL SELECT ParamID FROM tbl3 UNION ALL SELECT ParamID FROM tbl3 -- 注意你原问题里写了两次tbl3,要是笔误成其他表直接替换就行 )
如果你的子查询结果里有重复值,且你想确保去重(比如担心重复值影响判断),可以把UNION ALL换成UNION,不过会牺牲一点性能,按需选择就行。
方法2:用NOT EXISTS替代(更安全)
如果子查询的ParamID可能存在NULL值,NOT IN会因为SQL的三值逻辑导致整个查询返回空结果(因为NULL和任何值比较都是UNKNOWN),这时候NOT EXISTS就更靠谱,而且查询优化器对它的处理往往更高效:
SELECT * FROM table1 t1 WHERE NOT EXISTS (SELECT 1 FROM tbl2 t2 WHERE t2.ParamID = t1.ParamID) AND NOT EXISTS (SELECT 1 FROM tbl3 t3 WHERE t3.ParamID = t1.ParamID) -- 如果还有第三个需要排除的表,继续加一行AND NOT EXISTS即可
这种写法逻辑更清晰,也避免了NULL带来的坑,我自己日常用得更多。
内容的提问来源于stack exchange,提问作者Nate Pet
相关产品推荐
相关产品推荐

