NOT IN子句和NULL值

这个问题出现了,当我得到不同的记录计数为我认为是相同的查询之一使用not in where约束和另一个left joinnot 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

上一篇: NOT IN clause and NULL values

下一篇: SQL: IF clause within WHERE clause