2

我尝试了一个在 Postrgresql、Spark 上测试 NULL NOT IN Empty_Relation 的查询,我得到了不同的结果。

select count(*) from
(select 1)
where null not in
(a empty relation)

Postgresql 输出 1。其他输出 0。

我理解 NOT IN 的 NULL 行为,但我的子查询是空关系,这种情况似乎更有趣。有很多帖子讨论 NOT IN,但我没有找到任何与 NOT IN Empty_Relation 相关的内容。

所以我的问题更像是 ANSI SQL 是否定义了这种行为,或者这实际上是一个灰色区域,两个答案都可以接受。

4

2 回答 2

4

tl;博士:PostgreSQL 是正确的。

这是 SQL 规范对这种行为所说的:

4) 表达式RVC NOT IN IPV等价于NOT ( RVC IN IPV )

5) 表达式RVC IN IPV等价于RVC = ANY IPV

所以,NULL NOT IN (<empty relation>)等价于NOT (NULL = ANY (<empty relation>))

然后,它继续说:

的结果R <comp op> <quantifier> T是通过将隐含<comparison predicate> R <comp op> RT应用于 中的每一行而得出RTT

[...]

d) 如果T为空或如果 中的<comparison predicate>每一行隐含为 False RTT则为R <comp op> <some> TFalse。

(注意:<some>ANY或者SOME——它们的意思相同)。

根据这个规则,因为T是空NULL = ANY (<empty>)的,所以是假的,所以NOT (NULL = ANY (<empty relation>)是真的。

于 2019-11-03T23:02:19.743 回答
2

我很确定 Postgres 是正确的。

尽管几乎每次与NULLreturn进行比较NULL,您都发现了一个例外。如果集合为空,则集合中没有任何内容。也就是说,无论值如何,任何值都不在集合中。

请记住,NULL平均“未知”值的语义——不是缺失值。“未知”意味着它可以取任何值。表达式<anything> not in (<empty set>)为真,与 的值无关<anything>

顺便说一句,Postgres 在这种行为中并不孤单。粗略地看一下,SQL Server 和 Oracle 也返回1等效查询。

于 2019-11-03T21:53:10.690 回答