如果b
可以为空,则这不是错误。问题是 SQL Server 变成NOT IN
了一系列<> 1 AND <> 2 AND <> 3
等。如果你有<> NULL
,那返回未知,在这种情况下意味着 false。在不同的情况下,这可以限定或取消所有行的资格。而不是LEFT JOIN
方法,你应该说:
FROM dbo.OuterTable AS t
WHERE NOT EXISTS (SELECT 1 FROM x WHERE b = t.a);
这是一个快速演示:
DECLARE @x TABLE(i INT);
INSERT @x VALUES(1),(2);
DECLARE @y TABLE(j INT);
INSERT @y VALUES(2),(NULL);
SELECT i FROM @x WHERE i NOT IN -- produces zero results
(SELECT j FROM @y);
SELECT i FROM @x AS x WHERE NOT EXISTS -- produces one result
(SELECT 1 FROM @y WHERE j = x.i);
有关更多详细信息(以及证明为什么NOT EXISTS
是最佳选择的指标):
http://www.sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join
另外,请阅读 Gail Shaw 的这篇博文:
http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/