SQL 查询的 NULL NOT IN (Empty_Relation) 在不同的引擎上显示不同的行为
NULL NOT IN (Empty_Relation) of SQL query shows different behaviors on different engines
我在 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 是否定义了这种行为,或者这实际上是一个灰色区域,两个答案都可以接受。
我很确定 Postgres 是正确的。
虽然几乎每一次与NULL
returnsNULL
的比较,你都发现了一个例外。如果集合为空,则集合中没有 nothing。也就是说,无论值如何,任何值 都不在集合中。
请记住,NULL
的语义意味着 "unknown" 值 -- 不是 缺失值。 "Unknown" 表示它可以取任何值。无论 <anything>
.
的值如何,表达式 <anything> not in (<empty set>)
都为真
顺便说一下,Postgres 并不是唯一有这种行为的。粗略地看一下 SQL Server 和 Oracle 也 return 1
用于等效查询。
tl;dr:PostgreSQL 是正确的。
这是 SQL 规范对这种行为的描述:
4) The expression RVC NOT IN IPV
is equivalent to NOT ( RVC IN IPV )
5) The expression RVC IN IPV
is equivalent to RVC = ANY IPV
所以,NULL NOT IN (<empty relation>)
等同于 NOT (NULL = ANY (<empty relation>))
然后,它继续说:
The result of R <comp op> <quantifier> T
is derived by the application of the implied <comparison predicate>
R <comp op> RT
to every row RT
in T
.
[...]
d) If T
is empty or if the implied <comparison predicate>
is False for every row RT
in T
, then R <comp op> <some> T
is False.
(注意:<some>
是 ANY
或 SOME
-- 它们的意思相同)。
按此规则,由于T
为空,NULL = ANY (<empty>)
为False,所以NOT (NULL = ANY (<empty relation>)
为True。
我在 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 是否定义了这种行为,或者这实际上是一个灰色区域,两个答案都可以接受。
我很确定 Postgres 是正确的。
虽然几乎每一次与NULL
returnsNULL
的比较,你都发现了一个例外。如果集合为空,则集合中没有 nothing。也就是说,无论值如何,任何值 都不在集合中。
请记住,NULL
的语义意味着 "unknown" 值 -- 不是 缺失值。 "Unknown" 表示它可以取任何值。无论 <anything>
.
<anything> not in (<empty set>)
都为真
顺便说一下,Postgres 并不是唯一有这种行为的。粗略地看一下 SQL Server 和 Oracle 也 return 1
用于等效查询。
tl;dr:PostgreSQL 是正确的。
这是 SQL 规范对这种行为的描述:
4) The expression
RVC NOT IN IPV
is equivalent toNOT ( RVC IN IPV )
5) The expression
RVC IN IPV
is equivalent toRVC = ANY IPV
所以,NULL NOT IN (<empty relation>)
等同于 NOT (NULL = ANY (<empty relation>))
然后,它继续说:
The result of
R <comp op> <quantifier> T
is derived by the application of the implied<comparison predicate>
R <comp op> RT
to every rowRT
inT
.[...]
d) If
T
is empty or if the implied<comparison predicate>
is False for every rowRT
inT
, thenR <comp op> <some> T
is False.
(注意:<some>
是 ANY
或 SOME
-- 它们的意思相同)。
按此规则,由于T
为空,NULL = ANY (<empty>)
为False,所以NOT (NULL = ANY (<empty relation>)
为True。