NULL NOT IN (Empty_Relation) SQL-запроса показывает разные варианты поведения на разных движках - PullRequest
2 голосов
/ 04 ноября 2019

Я пытаюсь выполнить запрос, который проверяет NULL NOT IN Empty_Relation на Postrgresql, Spark и я получил разные результаты.

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

Выводы Postgresql 1. Другие выводы 0.

Я понимаюNULL поведение NOT IN, но мой подзапрос - пустое отношение, эта ситуация кажется более интересной. Есть много постов, в которых обсуждается NOT IN, но я не нахожу ничего связанного с NOT IN. может быть принято.

Ответы [ 2 ]

4 голосов
/ 04 ноября 2019

tl; dr : 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 к каждой строке RT в T.

[...]

d) Если T пусто или подразумеваемое <comparison predicate> является ложным для каждой строки RT в T, то R <comp op> <some> T является ложным.

(Примечание: <some> это либо ANY, либо SOME - они оба означают одно и то же).

По этому правилу, поскольку T пусто, NULL = ANY (<empty>) является ложным, поэтому NOT (NULL = ANY (<empty relation>) является истинным.

2 голосов
/ 04 ноября 2019

Я почти уверен, что Postgres верен.

Хотя почти каждое сравнение с NULL возвращает NULL, вы нашли исключение. Если набор пуст, то none в наборе. То есть любое значение НЕ находится в наборе независимо от значения.

Помните, семантика NULL означает «неизвестное» значение - не отсутствуетстоимость. «Неизвестный» означает, что он может принимать любое значение. Выражение <anything> not in (<empty set>) является истинным, независимо от значения <anything>.

Кстати, Postgres не одинок в этом поведении. Беглый взгляд показывает, что SQL Server и Oracle также возвращают 1 для эквивалентных запросов.

...