首页 > 解决方案 > Unkown 是否等同于 PostgreSQL 中的 Null?

问题描述

我的查询中有一些复杂的比较,我想确保在存在空值的情况下正确理解逻辑。似乎“未知”与 PostgreSQL 中的“空”是一样的,我没想到会这样。

这是我的例子:

create table tab (col int);

insert into tab (col) values (7), (11), (null);


select col,
  (col = 7) is true as is_true,
  (col = 7) is false as is_false,
  (col = 7) is unknown as is_unknown,
  (col = 7) is null as is_null
  from tab;

它显示输出:

+-----+--------+---------+-----------+--------+
|a    |is_true |is_false |is_unknown |is_null |
+-----+--------+---------+-----------+--------+
|7    |true    |false    |false      |false   |
|11   |false   |true     |false      |false   |
|null |false   |false    |true       |**true**|
+-----+--------+---------+-----------+--------+

最后一个值不应该是“假”而不是“真”吗?

标签: sqlpostgresqllogical-operators

解决方案


这就是 SQL 标准对 NULL 值的规定:

每种数据类型都包含一个特殊值,称为空值,有时用关键字表示NULL。该值在以下方面不同于其他值:

  • 由于空值存在于每种数据类型中,因此NULL无法推断出关键字所隐含的空值的数据类型;因此NULL只能在某些上下文中用于表示空值,而不是在允许使用文字的任何地方。
  • 尽管空值既不等于任何其他值,也不等于任何其他值——它是否等于任何给定值是未知的——在某些情况下,多个空值被一起处理;例如,<group by 子句> 将所有空值一起处理。

这就是标准对布尔值所说的:

数据类型 boolean 包含不同的真值TrueFalse。除非被 NOT NULL 约束禁止,否则布尔数据类型还支持真值Unknown作为空值。本规范不区分布尔数据类型的空值和作为 SQL <predicate>、<search condition> 或 <boolean value expression> 的结果的真值Unknown ;它们可以互换使用,表示完全相同的东西。

所以对于 a boolean, 和IS NULL是一样的IS UNKNOWN。如果你说它与 NULL 相同,你可能会说声明一个“未知”值有点愚蠢,但这就是 SQL 标准的方式。

但是,当您考虑有多少人正确理解 NULL 时,它会产生以下陈述,这感觉像是一个深刻的事实:

SELECT NULL IS UNKNOWN;

 ?column? 
══════════
 t
(1 row)

推荐阅读