为什么`NOT(NULL = NULL)`false?

时间:2017-04-10 10:43:20

标签: sql sql-server null logical-operators three-valued-logic

(NULL = NULL) false 。精细。记住为" NULL被定义为不等于任何"。

(NULL = NULL) false 。呃......好的,公平的。记住为" NULL表示未定义的值,因此您永远不知道它是否等于其他内容"。

NOT(NULL = NULL) false 。等等,什么!?

说真的,这怎么可能有效? " NOT()"的行为怎么样?运算符取决于正在评估的表达式的详细信息!? 所有SQL系统都这样做吗?

<小时/> 演示查询:

SELECT '"1 & 1"',
       '"1 = 1" is ' + (CASE WHEN (1=1) THEN 'true' ELSE 'false' END) AS 'a=b',
       '"1 <> 1" is ' + (CASE WHEN (1<>1) THEN 'true' ELSE 'false' END) AS 'a<>b',
       '"NOT(1=1)" is ' + (CASE WHEN NOT(1=1) THEN 'true' ELSE 'false' END) AS 'NOT(a=b)',
       '"NOT(1<>1)" is ' + (CASE WHEN NOT(1<>1) THEN 'true' ELSE 'false' END) AS 'NOT(a<>b)'
UNION
SELECT '"1 & 2"',
       '"1 = 2" is ' + (CASE WHEN (1=2) THEN 'true' ELSE 'false' END)AS 'a=b',
       '"1 <> 2" is ' + (CASE WHEN (1<>2) THEN 'true' ELSE 'false' END)AS 'a<>b',
       '"NOT(1=2)" is ' + (CASE WHEN NOT(1=2) THEN 'true' ELSE 'false' END)AS 'NOT(a=b)',
       '"NOT(1<>2)" is ' + (CASE WHEN NOT(1<>2) THEN 'true' ELSE 'false' END) AS 'NOT(a<>b)'
UNION
SELECT '"NULL & 1"',
       '"NULL = 1" is ' + (CASE WHEN (NULL=1) THEN 'true' ELSE 'false' END) AS 'a=b',
       '"NULL <> 1" is ' + (CASE WHEN (NULL<>1) THEN 'true' ELSE 'false' END) AS 'a<>b',
       '"NOT(NULL=1)" is ' + (CASE WHEN NOT(NULL=1) THEN 'true' ELSE 'false' END) AS 'NOT(a=b)',
       '"NOT(NULL<>1)" is ' + (CASE WHEN NOT(NULL<>1) THEN 'true' ELSE 'false' END) AS 'NOT(a<>b)'
UNION
SELECT '"NULL & NULL"',
       '"NULL = NULL" is ' + (CASE WHEN (NULL=NULL) THEN 'true' ELSE 'false' END)AS 'a=b',
       '"NULL <> NULL" is ' + (CASE WHEN (NULL<>NULL) THEN 'true' ELSE 'false' END)AS 'a<>b',
       '"NOT(NULL=NULL)" is ' + (CASE WHEN NOT(NULL=NULL) THEN 'true' ELSE 'false' END)AS 'NOT(a=b)',
       '"NOT(NULL<>NULL)" is ' + (CASE WHEN NOT(NULL<>NULL) THEN 'true' ELSE 'false' END) AS 'NOT(a<>b)'

2 个答案:

答案 0 :(得分:7)

three-valued logic (3VL)将逻辑运算符定义为:

+---------+---------+---------+---------+---------+
| p       | q       | p OR q  | p AND q | p = q   |
+---------+---------+---------+---------+---------+
| True    | Unknown | True    | Unknown | Unknown |
| False   | Unknown | Unknown | False   | Unknown |
| Unknown | True    | True    | Unknown | Unknown |
| Unknown | False   | Unknown | False   | Unknown |
| Unknown | Unknown | Unknown | Unknown | Unknown |
+---------+---------+---------+---------+---------+

NOT 行为具有以下真值表:

+---------+---------+
| p       | NOT p   |
+---------+---------+
| True    | False   |
| False   | True    |
| Unknown | Unknown |
+---------+---------+

因此,在表达式NOT(NULL = NULL)中,您得到:

NULL = NULL -> Unknown
NOT(Unknown) -> Unknown

您的案例条件总是像未履行,因为您的表达式评估为未知,即既不是真也不是

有关SQL Server处理空值的方式的更多信息,请查看Why does NULL = NULL evaluate to false in SQL server

答案 1 :(得分:0)

原因是NULL表示缺少值或未知值。 SQL在选择这些含义之一时并不一致,但是在大多数情况下,NULL的行为就像一个未知值。

NULL = NULL返回NULL,因为如果比较两个未知值,结果将是未知的。它们可以相同或不同。

有多种方法可以处理NULL。最常见的是IS NULLIS NOT NULL语法。但是,您也可以以NULL-安全的方式比较两个值。在这种情况下,使用的语法取决于您使用的DBMS。更多详细信息here