7.4. Сочетание запросов (UNION, INTERSECT, EXCEPT)#
7.4. Сочетание запросов (UNION
, INTERSECT
, EXCEPT
) #
Результаты двух запросов могут быть объединены с помощью операций над множествами: объединение (union), пересечение (intersection) и разность (difference). Синтаксис следующий:
query1
UNION [ALL]query2
query1
INTERSECT [ALL]query2
query1
EXCEPT [ALL]query2
где query1
и
query2
- это запросы, которые могут использовать любые из
рассмотренных до этого момента функций.
Соединение (UNION
) эффективно добавляет результат query2
к результату query1
(хотя нет гарантии, что это будет порядок, в котором строки фактически возвращаются). Кроме того, оно удаляет дублирующиеся строки из результата, так же, как DISTINCT
, если не используется UNION ALL
.
INTERSECT
возвращает все строки, которые присутствуют как в результате query1
, так и в результате query2
. Дублирующиеся строки удаляются, если не используется INTERSECT ALL
.
EXCEPT
возвращает все строки, которые есть в результате
query1
, но отсутствуют в результате
query2
. (Иногда это называется
разницей между двумя запросами). Опять же, дубликаты
удаляются, если не используется EXCEPT ALL
.
Для вычисления объединения, пересечения или разности двух запросов эти два запроса должны быть "совместимыми для объединения", что означает, что они возвращают одинаковое количество столбцов, и соответствующие столбцы имеют совместимые типы данных, как описано в разделе Раздел 10.5.
Операции над множествами могут быть объединены, например
query1
UNIONquery2
EXCEPTquery3
что эквивалентно
(query1
UNIONquery2
) EXCEPTquery3
Как показано здесь, вы можете использовать скобки для управления порядком вычислений. Без скобок, операторы UNION
и EXCEPT
ассоциируются слева направо, но оператор INTERSECT
связывается более плотно, чем эти два оператора. Таким образом
query1
UNIONquery2
INTERSECTquery3
означает
query1
UNION (query2
INTERSECTquery3
)
Также можно заключить отдельный query
в скобки. Это важно, если query
должен использовать любые из обсуждаемых в следующих разделах операторов, таких как LIMIT
. Без скобок вы получите синтаксическую ошибку, или же оператор будет понят как применяемый к результату операции над множествами, а не к одному из его входных множеств. Например,
SELECT a FROM b UNION SELECT x FROM y LIMIT 10
is accepted, but it means
(SELECT a FROM b UNION SELECT x FROM y) LIMIT 10
не
SELECT a FROM b UNION (SELECT x FROM y LIMIT 10)