2010-04-02 63 views
5

我花了一些时间,试图为什么这个查询不拉,结果我希望弄清楚:为什么“不存在”的SQL查询工作,“不是”不

SELECT * FROM NGS WHERE ESPSSN NOT IN (SELECT SSN FROM CENSUS) 

最后我尝试编写查询另一种方式和最终获得了预期的效果:

SELECT * FROM NGS n WHERE NOT EXISTS (SELECT * FROM CENSUS WHERE SSN = n.ESPSSN) 

第一个查询似乎更合适,更“正确”。我一直使用“in”和“not in”来进行类似的选择,并且从来没有遇到过,我知道

回答

11

如果你写出来的语法糖,x not in (1,2,3)变为:

x <> 1 AND x <> 2 AND x <> 3 

因此,如果ssn列包含空值,第一个查询是等价的:

WHERE ESPSSN <> NULL AND ESPSSN <> ... 

的结果与NULL的比较是未知的,所以查询不会返回任何东西。

+0

良好的通话!我刚查过,表中有一个空值。将查询重写为SELECT * FROM NGS WHERE ESPSSN NOT IN(SELECT ISNULL(SSN,'')FROM CENSUS)给了我期望的值。我想知道我应该使用哪一个? – Josh 2010-04-02 17:47:25

+0

@Josh:我默认为'not exists',因为它不会受到'null'的困扰。但是,如果您有性能问题,那么可以考虑这两个选项的查询计划 – Andomar 2010-04-02 17:52:30

+0

@Josh,@Andomar:ISNULL将使任何可能在 – gbn 2010-04-02 18:21:23

2

正如Andomar表示,采用NOT IN

还要注意,使用NOT IN谓词的查询将利用NOT EXISTS可以使用子查询内的索引始终执行嵌套全表扫描,而查询时提防NULL值的,结果会更快。

+0

之前使用的索引无效。谢谢。 – Josh 2010-04-02 17:48:12