7.4. Сочетание запросов
Результаты двух запросов можно обработать, используя операции над множествами: объединение, пересечение и вычитание. Эти операции записываются соответственно так:
запрос1
UNION [ALL]запрос2
запрос1
INTERSECT [ALL]запрос2
запрос1
EXCEPT [ALL]запрос2
Здесь запрос1
и запрос2
— это запросы, в которых могут использоваться все возможности, рассмотренные до этого.
UNION
по сути добавляет результаты второго запроса к результатам первого (хотя никакой порядок возвращаемых строк при этом не гарантируется). Более того, эта операция убирает дублирующиеся строки из результата так же, как это делает DISTINCT
, если только не указано UNION ALL
.
INTERSECT
возвращает все строки, содержащиеся в результате и первого, и второго запроса. Дублирующиеся строки отфильтровываются, если не указано ALL
.
EXCEPT
возвращает все строки, которые есть в результате первого запроса, но отсутствуют в результате второго. (Иногда это называют разницей двух запросов.) И здесь дублирующиеся строки отфильтровываются, если не указано ALL
.
Чтобы можно было вычислить объединение, пересечение или разницу результатов двух запросов, эти запросы должны быть «совместимыми для объединения», что означает, что они должны иметь одинаковое число столбцов и соответствующие столбцы должны быть совместимых типов, как описывается в Разделе 10.5.
Операции над множествами можно объединять, например
запрос1
UNIONзапрос2
EXCEPTзапрос3
что равнозначно
(запрос1
UNIONзапрос2
) EXCEPTзапрос3
Как показано выше, вы можете использовать круглые скобки, чтобы управлять очередью обработки. Без круглых скобок UNION
и EXCEPT
объединяются слева направо, но оператор INTERSECT
имеет больший приоритет, чем первые два. Таким образом,
запрос1
UNIONзапрос2
INTERSECTзапрос3
означает
запрос1
UNION (запрос2
INTERSECTзапрос3
)
Вы также можете заключить отдельный запрос
в круглые скобки. Это важно, если в запросе
необходимо использовать любое из предложений, обсуждаемых в следующих разделах, например 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)