当我得到不同的记录计数时,这个问题出现了,我认为是相同的查询,一个使用not in where约束,另一个使用左连接。not in约束中的表有一个空值(坏数据),导致该查询返回0条记录计数。我有点理解为什么,但我需要一些帮助来充分理解这个概念。
简单地说,为什么查询A返回结果而B没有?
A: select 'true' where 3 in (1, 2, 3, null)
B: select 'true' where 3 not in (1, 2, null)
这是在SQL Server 2005上。我还发现调用set ansi_nulls off会导致B返回一个结果。
当你使用NULL时,你实际上是在处理一个三值逻辑。
你的第一个查询返回WHERE子句的结果:
3 = 1 or 3 = 2 or 3 = 3 or 3 = null
which is:
FALSE or FALSE or TRUE or UNKNOWN
which evaluates to
TRUE
第二点:
3 <> 1 and 3 <> 2 and 3 <> null
which evaluates to:
TRUE and TRUE and UNKNOWN
which evaluates to:
UNKNOWN
“未知”并不等同于“虚假”
你可以通过调用:
select 'true' where 3 <> null
select 'true' where not (3 <> null)
这两个查询都不会得到结果
如果UNKNOWN与FALSE相同,那么假设第一个查询会给你FALSE,那么第二个查询就必须计算为TRUE,因为它与NOT(FALSE)相同。
事实并非如此。
在SqlServerCentral上有一篇关于这个主题的非常好的文章。
null和三值逻辑的整个问题一开始可能有点令人困惑,但为了在TSQL中编写正确的查询,理解它是必不可少的
我要推荐的另一篇文章是SQL聚合函数和NULL。