NOT IN子句和NULL值
这个问题出现了,当我得到不同的记录计数为我认为是相同的查询之一使用not in
where
约束和另一个left join
。 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返回结果。
查询A与以下内容相同:
select 'true' where 3 = 1 or 3 = 2 or 3 = 3 or 3 = null
由于3 = 3
是真的,你会得到一个结果。
查询B与以下内容相同:
select 'true' where 3 <> 1 and 3 <> 2 and 3 <> null
当ansi_nulls
打开时, 3 <> null
是UNKNOWN,所以谓词的计算结果为UNKNOWN,并且没有任何行。
当ansi_nulls
关闭时, 3 <> null
为真,因此谓词的计算结果为true,并且您得到一行。
每当你使用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
UNKNOWN与FALSE不同,您可以通过调用以下方法轻松测试它:
select 'true' where 3 <> null
select 'true' where not (3 <> null)
这两个查询都不会给你任何结果
如果UNKNOWN与FALSE相同,那么假定第一个查询会给你假,第二个查询将不得不评估为TRUE,因为它将与NOT(FALSE)相同。
事实并非如此。
SqlServerCentral上有关于此主题的非常好的文章。
整个NULL和三值逻辑的问题最初可能有点令人困惑,但为了在TSQL中编写正确的查询,理解这一点非常重要
另一篇我会推荐的文章是SQL Aggregate Functions和NULL。
与null比较是未定义的,除非您使用IS NULL。
所以,当比较3到NULL(查询A)时,它返回undefined。
Ie SELECT'true'where 3 in(1,2,null)and SELECT'true'where 3 not in(1,2,null)
将产生相同的结果,因为NOT(UNDEFINED)仍未定义,但不是TRUE
链接地址: http://www.djcxy.com/p/44019.html