7.4. Сочетание запросов (UNION, INTERSECT, EXCEPT)#
7.4. Сочетание запросов (UNION, INTERSECT, EXCEPT) #
Результаты двух запросов можно объединить с помощью операций над множествами: объединение (union), пересечение (intersection) и вычитание (difference). Синтаксис следующий:
query1UNION [ALL]query2query1INTERSECT [ALL]query2query1EXCEPT [ALL]query2
где query1 и
query2 — это запросы, которые могут использовать любые из
рассмотренных до этого момента функций.
(UNION) фактически добавляет результат query2 к результату query1 (хотя какой-то определенный порядок возвращаемых строк не гарантируется). Кроме того, данная операция удаляет дублирующиеся строки из результата, так же, как DISTINCT, если не используется UNION ALL.
INTERSECT возвращает все строки, которые содержатся как в результате query1, так и в результате query2. Дублирующиеся строки удаляются, если не используется INTERSECT ALL.
EXCEPT возвращает все строки, которые содержатся в результате
query1, но отсутствуют в результате
query2. (Иногда это называется
разницей между двумя запросами). Опять же, дубликаты
удаляются, если не используется EXCEPT ALL.
Для вычисления объединения, пересечения или разности результатов двух запросов эти два запроса должны быть "совместимыми для объединения", что означает, что они возвращают одинаковое количество столбцов, и соответствующие столбцы имеют совместимые типы данных, как описано в разделе Раздел 10.5.
Операции над множествами могут быть объединены, например так:
query1UNIONquery2EXCEPTquery3
что эквивалентно
(query1UNIONquery2) EXCEPTquery3
Как показано выше, вы можете использовать скобки для управления очередью вычислений. Без скобок, операторы UNION и EXCEPT объединяются слева направо, но оператор INTERSECT имеет более высокий приоритет, чем эти два оператора. Таким образом
query1UNIONquery2INTERSECTquery3
означает
query1UNION (query2INTERSECTquery3)
Также можно заключить отдельный 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)