T-SQL中WHERE EXISTS与INTERSECT的差异及结果不同原因咨询
这俩SQL写法看起来都是找两张表共有的CustID,但核心逻辑差得挺多,导致结果行数不同,主要原因有这几点:
重复值的处理逻辑完全不同
EXISTS是做存在性检查——只要tbl1里的某一行CustID在tbl2里能找到匹配,不管tbl1里这个CustID重复多少次,每一行都会被返回。比如tbl1里同一个CustID出现10次,只要tbl2有这个值,这10行都会出现在结果里。
而INTERSECT是求两个结果集的交集且自动去重,它会把两边的结果先去重,再找共同的部分。哪怕tbl1里同一个CustID重复N次,INTERSECT最终只会保留唯一的那一个。这应该就是你这里行数差(178 vs 162)的核心原因——你的tbl1里存在重复的CustID记录,这些重复行被EXISTS全部输出,但被INTERSECT合并成了唯一行。NULL值的处理差异(如果你的CustID允许为空的话)
标准SQL里,EXISTS只关心子查询有没有返回行,不管行里的值是不是NULL;而INTERSECT会把两个NULL视为相等的值(符合集合交集的逻辑)。不过看你的字段是CustID,大概率是主键或者非空约束,这个因素可能没影响到你,但还是值得知道。底层执行逻辑的区别
EXISTS本质是半连接(Semi-Join),数据库找到第一个匹配的行后就会停止对当前CustID的后续查找,效率可能更高,但会保留原表的重复数据;而INTERSECT相当于先分别执行两个SELECT,再对两个结果集做去重和交集运算,相当于隐含了DISTINCT的逻辑。
验证方法
你可以给EXISTS的查询加上DISTINCT试试:
SELECT DISTINCT a.CustID FROM tbl1 AS a WHERE EXISTS (SELECT b.CustID FROM tbl2 b WHERE a.CustID=b.CustID)
如果这个查询返回162行,那就实锤是重复值导致的差异了。
内容的提问来源于stack exchange,提问作者sqluser

