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
не генерирует ошибку, но означает
(SELECT a FROM b UNION SELECT x FROM y) LIMIT 10
не
SELECT a FROM b UNION (SELECT x FROM y LIMIT 10)