为什么 SQL 最终将 NULL 值视为 FALSE?

Why SQL does finally treat a NULL value as FALSE?

因为 NULL 它只是一个未知值或缺失值,所以可能是 TRUE 但我们不知道。为什么FALSE推定?除了 "it's obvious" 之外,它是否有任何理由(因为它不是)或者应该被视为一种 SQL 糟糕的设计工件?

例如:

SELECT * FROM `rainbow_table` WHERE `show_me`

有些行为空 show_me。我们真的不知道是否应该输出这样的行,也许最好显示它(作为防止数据丢失的最后机会)?好像SQL是悲观主义者开发的

SQL 并没有真正将 NULL 视为假。相反,只有当条件计算结果为真时,条件语句才被视为真。

效果是NULL被当成false。但这并不意味着NULL等同于false。

在SQL中,NULL表示它有一些值,但我们不知道它是什么。这就是为什么我们比较时会这样使用

Select * from table [table name] where [column name] is not NULL

问题是 Sql Server 引擎是建立在三值谓词逻辑之上的。如果谓词比较 2 个非空值,那么它可以被评估为 TRUEFALSE。如果 then 中至少有一个是 NULL,则 predicate 的计算结果为第三个逻辑值 - UNKNOWN.

现在 WHERE 子句中发生了什么?它的设计方式是 returns 行,其中谓词的计算结果仅为 TRUE!如果谓词的计算结果为 FALSEUNKNOWN,则相应的行会从结果集中过滤掉。

起初这非常令人困惑,并且会导致新手进入 SQL 的世界时犯几个典型的错误。他们只是不认为数据可能包含 NULLs。例如,其中一个经典错误是:

Employyes(Name varchar, Contry varchar) 
'John', 'USA'
'Peter', NULL
'Mike', 'England'

并且您想要 Contry 不是 USA 的所有行。你只需写:

select * from Employees where Country <> 'USA'

并且只得到:

'Mike', 'England'

结果。乍一看这很令人困惑,但据您了解引擎正在执行三值逻辑,结果是合乎逻辑的。

SELECT 语句的上下文中(因此,在 ON 子句、WHERE 子句和 CASE 表达式中),谓词必须是 TRUE(不是 FALSEUNKNOWN1)要满足的谓词。

但是,在 CHECK 限制条件下,谓词不能 FALSE 才能得到满足。

即以下脚本将起作用:

CREATE TABLE T (
  ID int not null,
  Val varchar(10) null,
  constraint CK_Vals CHECK (Val in ('abc','def'))
);
INSERT INTO T(ID,Val) VALUES (10,NULL);

因此我们可以看出,在 SQL 中 UNKNOWN 结果被视为 FALSE 并非 普遍 正确。用 NOT (<existing predicate>) 包装产生 UNKNOWN 的谓词不会产生 TRUE.

的事实也证明了这一点。

Three-Valued logic 上的维基百科页面涵盖了很多细节。


1我假设你的问题是关于 UNKNOWN 而不是 NULL,因为你已经标记 and . In standard SQL, UNKNOWN and NULL are two distinctly different concepts. Only (so far as I'm aware) 将两者混为一谈.