为什么 `NOT(NULL=NULL)` 是假的?
Why is `NOT(NULL=NULL)` false?
(NULL = NULL)
是 false。美好的。记为"NULL is defined not to be equal to anything".
(NULL = NULL)
是 false。呃……好吧,很公平。记为"NULL represents an undefined value, so you never know whether it is or isn't equal to something else".
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)'
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行为具有以下事实table:
+---------+---------+
| p | NOT p |
+---------+---------+
| True | False |
| False | True |
| Unknown | Unknown |
+---------+---------+
因此,在表达式 NOT(NULL = NULL)
中,您得到:
NULL = NULL -> Unknown
NOT(Unknown) -> Unknown
您的案例条件总是表现得像 未满足,因为您的表达式计算结果为未知,即 既非真又非假。
有关 SQL 服务器处理空值的方式的更多信息,请查看 Why does NULL = NULL evaluate to false in SQL server
原因是NULL
是为了表示没有值或未知值。 SQL 在选择这些含义之一时并不一致,但在大多数情况下 NULL
表现得像一个未知值。
NULL = NULL
returns NULL
因为,如果比较两个未知值,结果是未知的。它们可以相同也可以不同。
有办法对付NULL
。最常见的是 IS NULL
和 IS NOT NULL
语法。但是您也可以以 NULL
安全的方式比较两个值。在这种情况下,要使用的语法取决于您使用的 DBMS。更多详情 here.
(NULL = NULL)
是 false。美好的。记为"NULL is defined not to be equal to anything".
(NULL = NULL)
是 false。呃……好吧,很公平。记为"NULL represents an undefined value, so you never know whether it is or isn't equal to something else".
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)'
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行为具有以下事实table:
+---------+---------+
| p | NOT p |
+---------+---------+
| True | False |
| False | True |
| Unknown | Unknown |
+---------+---------+
因此,在表达式 NOT(NULL = NULL)
中,您得到:
NULL = NULL -> Unknown
NOT(Unknown) -> Unknown
您的案例条件总是表现得像 未满足,因为您的表达式计算结果为未知,即 既非真又非假。
有关 SQL 服务器处理空值的方式的更多信息,请查看 Why does NULL = NULL evaluate to false in SQL server
原因是NULL
是为了表示没有值或未知值。 SQL 在选择这些含义之一时并不一致,但在大多数情况下 NULL
表现得像一个未知值。
NULL = NULL
returns NULL
因为,如果比较两个未知值,结果是未知的。它们可以相同也可以不同。
有办法对付NULL
。最常见的是 IS NULL
和 IS NOT NULL
语法。但是您也可以以 NULL
安全的方式比较两个值。在这种情况下,要使用的语法取决于您使用的 DBMS。更多详情 here.