20

我对以下推理感到困惑:

SELECT * FROM table WHERE avalue is null

返回 '​​avalue' 为空的 x 行数

SELECT * FROM table WHERE avalue <> true

不返回“avalue”为空的行

我的推理(这似乎是不正确的)是null唯一值(它甚至不等于null)意味着它应该显示在结果集中,因为它不等于true任何一个。

我猜你可能会说column <> value你暗示该列有一个值,因此null完全忽略了这些值。

这背后的原因是什么,这在其他常见的 SQL DB 中是否相同?

我的推理(假设)告诉我这是违反直觉的,我想知道为什么。

4

3 回答 3

34

每一个体面的 RDBMS 都以同样的方式做这件事,因为它是正确的。
我在这里引用 Postgres 手册

当任一输入为空时,普通比较运算符产生空值(表示“未知”),而不是真或假。例如,7 = NULL产生 null 和7 <> NULL. 当此行为不合适时,请使用以下 IS [ NOT ] DISTINCT FROM构造:

expression IS DISTINCT FROM expression
expression IS NOT DISTINCT FROM expression

请注意,这些表达式的执行速度比简单expression <> expression比较要慢一些。

对于boolean值,也有更简单的IS NOT [TRUE | FALSE].
要在第二个查询中获得您期望的结果,请编写:

SELECT * FROM table WHERE avalue IS NOT TRUE;

SQL小提琴。

于 2013-07-16T15:31:27.360 回答
6

此链接提供了有用的见解。正如@Damien_The_Unbeliever 指出的那样,它有效地使用了三值逻辑,并且似乎(根据文章)是辩论的主题。

其他几个很好的链接可以在这里这里找到。

我认为它归结为 null 不是一个值,而是一个值的占位符,必须做出决定,就是这样......所以 NULL 不等于任何值,因为它不是一个值并且赢了'甚至不等于任何价值......如果这是有道理的。

于 2013-07-16T15:15:16.740 回答
2

这是正常的。SQL Server 以相同的方式执行此操作。在 SQL Server 中,您可以使用

SELECT * FROM table WHERE ISNULL(avalue, 0) <> 1

对于 postgresql 等价物,请注意:什么是 ISNULL() 的 PostgreSQL 等价物

如果有意义,请考虑使用具有默认值的 NOT NULL 列规范。

编辑:

我认为这是逻辑。NULL 不是一个值,因此它被排除在搜索之外 - 您必须明确指定它。如果 SQL 设计人员决定采用第二种方式(自动包含空值),那么如果您不需要识别任何值,您将遇到更多麻烦

于 2013-07-16T15:12:04.340 回答