Объединение

Предложение UNION объединяет два и более набора данных, тем самым увеличивая общее количество строк, но не столбцов. Наборы данных, принимающие участие в UNION, должны иметь одинаковое количество столбцов. Однако столбцы в соответствующих позициях не обязаны иметь один и тот же тип данных, они могут быть абсолютно не связанными. По умолчанию, объединение подавляет дубликаты строк. UNION ALL отображает все строки, включая дубликаты. Необязательное ключевое слово DISTINCT делает поведение по умолчанию явным.

Синтаксис

    SELECT ... FROM ...
    UNION [DISTINCT | ALL]
    SELECT ... FROM ...
    ...
    [UNION [DISTINCT | ALL]
    SELECT ... FROM ...]
    [...]

    [ORDER BY <элементы сортировки>]

Объединения получают имена столбцов из первого запроса на выборку. Если требуется дать псевдонимы объединяемым столбцам, то это необходимо делать для списка столбцов в самом верхнем запросе на выборку. Псевдонимы в других участвующих в объединении выборках разрешены, и могут быть даже полезными, но они не будут распространяться на уровне объединения. Если объединение имеет предложение ORDER BY, то единственно возможными элементами сортировки являются целочисленные литералы, указывающие на позиции столбцов, необязательно сопровождаемые ASC или DESC и NULLS FIRST и NULLS LAST директивами. Это так же означает, что нельзя упорядочить объединение ничем, что не является столбцом объединения. (Однако можно завернуть его в производную таблицу, которая даст возможность использовать все обычные параметры сортировки.) Объединения позволены в подзапросах любого вида и могут самостоятельно содержать подзапросы. Они также могут содержать соединения (joins), и могут принимать участие в соединениях, если завёрнуты в производную таблицу.

Например, запрос представляет информацию из различных музыкальных коллекций в одном наборе данных с помощью объединений:

SELECT id, title, artist, len, 'CD' AS medium
FROM cds
UNION
SELECT id, title, artist, len, 'LP'
FROM records
UNION
SELECT id, title, artist, len, 'MC'
FROM cassettes
ORDER BY 3, 2 -- artist, title

Следующий запрос получает имена и телефонные номера переводчиков и корректоров. Те переводчики, которые также работают корректорами, будут отображены только один раз в результирующем наборе, если номера их телефонов одинаковые в обеих таблицах. Тот же результат может быть получен без ключевого слова DISTINCT. Если вместо ключевого слова DISTINCT, будет указано ключевое слово ALL, эти люди будут отображены дважды.

SELECT name, phone FROM translators
UNION DISTINCT
SELECT name, telephone FROM proofreaders 

Пример использования UNION в подзапросе:

SELECT name, phone, hourly_rate FROM clowns
    WHERE hourly_rate < ALL 
    (SELECT hourly_rate FROM jugglers
        UNION
    SELECT hourly_rate FROM acrobats)
ORDER BY hourly_rate

Контрольные вопросы

  1. Что будет, если объединяемые запросы будут содержать разное количество столбцов?
  2. Что будет, если соответствующие столбцы объединяемых запросов будут иметь разные названия?
  3. Что будет, если соответствующие столбцы объединяемых запросов будут иметь разные типы данных?
  4. Можно ли упорядочить объединение нескольких запросов и как?
  5. Как управлять подавлением дубликатов в результате объединения и что является поведением по умолчанию?