在PostgreSQL(可能还有其他引擎)中,为什么UNION语句认为NULL值相同,而UNIQUE约束则不然?

Sha*_*ter 5 sql union null dbnull duplicates

我知道SQL标准允许列中的多个NULL值是UNIQUE约束的一部分.

我不明白为什么UNION构造(至少在PostgreSQL中)将NULL值视为相同.例如:

$ select * from tmp_a;
 a | b
---+---
 a | b
 a |
   |
(3 rows)

$ select * from tmp_b;
 a | b
---+---
 a | c
 a |
   |
(3 rows)

$ select a, b from tmp_a union select a, b from tmp_b order by 1, 2;
 a | b
---+---
 a | b
 a | c
 a |
   |
(4 rows)
Run Code Online (Sandbox Code Playgroud)

one*_*hen 2

SQL-92 标准中的一般规则如下:

13.1“声明游标”(记住ORDER BY是游标的一部分)一般规则 3b:

下面对空值进行特殊处理。为 null 的排序键值是否被视为大于或小于非空值是实现定义的,但所有为 null 的排序键值应被视为大于所有非空值或被视为小于所有非空值。 -空值。

在我看来,SQL-89 更清楚地说明了这一点:

尽管x = y未知 和 是否 x均为y值,但在、和 的 NULL上下文中,一个值与另一个值相同或重复。GROUP BYORDER BYDISTINCTNULLNULL

我猜测 PostgreSQL 正在按照标准的要求执行排序以删除重复项,UNION并且NULL按照标准将值分组在一起。