Порядок выполнения операторов UNION, EXCEPT, INTERSECT
В связи с упражнением 6 (SELECT) рейтингового этапа возник вопрос относительно старшинства операций UNION, EXCEPT и INTERSECT. Логический порядок выполнения этих операций, который приводится в книге Мартина Грабера [4] “Справочное руководство по SQL”, выглядит так:
В предположении, что логический порядок выполнения операций соответствует их старшинству, получается, что старшинство операций UNION и EXCEPT идентично и, следовательно, они должны выполняться в том порядке, в котором записаны, если этот порядок не изменяется скобками. При этом обе операции выполняются раньше, чем INTERSECT, т.е. они старше.
Рассмотрим три простых запроса, которые будем комбинировать различными способами, чтобы убедиться в этом:
[[ column ]] |
---|
NULL
[[ value ]] |
model | type |
---|
1121 | PC |
1750 | Laptop |
[[ column ]] |
---|
NULL
[[ value ]] |
model | type |
---|
1298 | Laptop |
1321 | Laptop |
1750 | Laptop |
1752 | Laptop |
[[ column ]] |
---|
NULL
[[ value ]] |
model | type |
---|
1121 | PC |
1232 | PC |
1233 | PC |
1260 | PC |
2111 | PC |
2112 | PC |
Давайте сначала проверим первое утверждение. Если операция EXCEPT старше операции UNION, то запросы
[[ column ]] |
---|
NULL
[[ value ]] |
и
[[ column ]] |
---|
NULL
[[ value ]] |
должны нам дать разные результаты. Однако это не так, и мы получаем один и тот же результирующий набор:
model | type |
---|
1298 | Laptop |
1321 | Laptop |
1750 | Laptop |
1752 | Laptop |
Аналогично, если операция UNION старше операции EXCEPT, то запросы
[[ column ]] |
---|
NULL
[[ value ]] |
и
[[ column ]] |
---|
NULL
[[ value ]] |
должны нам дать разные результаты. И тут мы получаем одинаковый результат:
model | type |
---|
1121 | PC |
1298 | Laptop |
1321 | Laptop |
1750 | Laptop |
1752 | Laptop |
Итак, операции UNION и EXCEPT эквивалентны по старшинству.
Проверим теперь старшинство операции INTERSECT по отношению к другим операторам (в тестах можно взять любую из них, т.к. они имеют один и тот же порядок).
Если INTERSECT “младше” или эквивалентен UNION, то запросы
[[ column ]] |
---|
NULL
[[ value ]] |
и
[[ column ]] |
---|
NULL
[[ value ]] |
должны дать одинаковые результаты. Однако мы получаем разные результирующие наборы. Первый запрос дает
model | type |
---|
1121 | PC |
1750 | Laptop |
в то время как второй
Вывод. Логический порядок, приведенный в начале статьи не соответствует старшинству операций, и, на мой взгляд, его следует поменять на обратный: