Компьютеры
и программирование

SQL UNION - объединение результатов запросов

Оператор языка SQL UNION предназначен для объединения результирующих таблиц базы данных, полученных с применением слова SELECT. Условие объединения результирующих таблиц: совпадение числа, порядка следования и типа данных столбцов. Оператор UNION имеет следующий синтаксис:

SELECT ИМЕНА_СТОЛБЦОВ (1..N) FROM ИМЯ_ТАБЛИЦЫ UNION SELECT ИМЕНА_СТОЛБЦОВ (1..N) FROM ИМЯ_ТАБЛИЦЫ

В этой конструкции объединяемые запросы могут иметь условия в секции WHERE, а могут не иметь их. При помощи оператора UNION можно объединить запросы на извлечение данных как из одной таблицы, так и из разных.

При использовании оператора UNION без слова ALL результат не содержит дубликатов, а со словом ALL - содержит дубликаты.

Пример 1. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. В ней есть столбцы Salary (размер заработной платы), Job (должность) и Years (длительность трудового стажа). Первый запрос нужен для получения данных о сотрудниках, заработная плата которых более 21000:

SELECT ID, Name FROM STAFF WHERE SALARY > 21000

Результатом выполнения запроса будет следующая таблица:

IDName
140Fraye
160Molinare
260Jones

Второй запрос возвращает имена сотрудников, должность которых "менеждер", а число лет трудового стажа - менее 8:

SELECT ID, Name FROM STAFF WHERE Job = 'Mgr' AND Years < 8 ORDER BY ID

Результатом выполнения запроса будет следующая таблица:

IDName
10Sanders
30Marenghi
100Plotz
140Fraye
160Molinare
240Daniels

Теперь требуются данные, в которых объединены критерии отбора, применённые в двух запросах. Объединяем запросы при помощи оператора UNION:

SELECT ID, Name FROM STAFF WHERE SALARY > 21000 UNION SELECT ID, Name FROM STAFF WHERE Job = 'Mgr' AND Years < 8 ORDER BY ID

Результатом выполнения запроса с оператором UNION будет следующая таблица:

IDName
10Sanders
30Marenghi
100Plotz
140Fraye
160Molinare
240Daniels
260Jones

Запрос с оператором UNION может возвращать и большее количество столбцов, важно, чтобы в объединяемых запросах число столбцов, порядок их следования и типы данных совпадали.

Пример 2. Есть база данных портала объявлений, о которой более подробно - в уроке об использовании JOIN (пример 7).

Пусть сначала требуется получить данные о категориях и частях категорий объявлений, в которых подано более 100 объявлений в неделю. Пишем следующий запрос:

SELECT Category, Part, Units, Money FROM ADS WHERE Units > 100

Результатом выполнения запроса будет следующая таблица:

CategoryPartUnitsMoney
ТранспортАвтомашины11017600
ТранспортМотоциклы13120960
ЭлектротехникаТелевизоры1278255
ЭлектротехникаХолодильники1378905
СтройматериалыРегипс11211760
ДосугМузыка1177605

Теперь требуется извлечь данные о категориях и частях категорий объявлений, за которые выручено более 10000 денежных единиц в неделю. Пишем следующий запрос:

SELECT Category, Part, Units, Money FROM ADS WHERE Money > 10000

Результатом выполнения запроса будет следующая таблица:

CategoryPartUnitsMoney
ТранспортАвтомашины11017600
НедвижимостьКвартиры8918690
НедвижимостьДачи5711970
ТранспортМотоциклы13120960
СтройматериалыРегипс11211760

Теперь требуется извлечь данные, которые соответствуют критериям и первого, и второго запросов. Объединяем запросы при помощи оператора UNION:

SELECT Category, Part, Units, Money FROM ADS WHERE Units > 100 UNION SELECT Category, Part, Units, Money FROM ADS WHERE Money > 10000

Результатом выполнения запроса будет следующая таблица:

ТранспортАвтомашины11017600
ТранспортМотоциклы13120960
НедвижимостьКвартиры8918690
НедвижимостьДачи5711970
ЭлектротехникаТелевизоры1278255
ЭлектротехникаХолодильники1378905
СтройматериалыРегипс11211760
ДосугМузыка1177605

До сих пор мы рассматривали запросы с оператором UNION, в которых объединялись результаты из одной таблицы. Теперь будем объединять результаты из двух таблиц.

Пример 3. Есть база данных склада строительных материалов. В ней есть таблицы, содержащая данные об обоях. Таблица Vinil содержит данные о виниловых обоях, таблица Paper - о бумажных обоях. Требуется узнать данные о ценах обоев из одной и другой таблицы.

Чтобы извлечь не повторяющиеся данные о ценах на виниловые обои, составим запрос со словом DISTINCT:

SELECT DISTINCT Price FROM VINIL

Результатом выполнения запроса будет следующая таблица:

Price
400
500
530
610
720
800
850

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

SELECT DISTINCT Price FROM PAPER

Результатом выполнения запроса будет следующая таблица:

Price
300
320
360
400
430
500
530

Теперь составим объединённый запрос с оператором UNION:

SELECT DISTINCT Price FROM VINIL UNION SELECT DISTINCT Price FROM PAPER

Так как мы не используем слово ALL, дубликаты значений 400, 500 и 530 выводиться не будут. Результатом выполнения запроса будет следующая таблица:

Price
300
320
360
400
430
500
530
610
720
800
850

Пример 4. База данных и таблицы - те же, что и в предыдущем примере.

Требуется получить все данные о ценах, в том числе повторяющиеся. Запрос на объединение результатов с использованием оператора UNION будет аналогичен запросу в предыдущем примере, но вместо просто UNION пишем UNION ALL:

SELECT DISTINCT Price FROM VINIL UNION ALL SELECT DISTINCT Price FROM PAPER

Результатом выполнения запроса будет следующая таблица:

Price
300
320
360
400
400
430
500
500
530
530
610
720
800
850

При помощи оператора SQL UNION можно объединить как простые запросы, так и запросы, содержащие подзапросы (вложенные запросы). Рассмотрим соответствующий пример.

Пример 5. Есть база данных "Театр". В её таблице Play содержатся данные о постановках (названия - в столбце Name), в таблице Director - даные о режиссёрах (в столбце Fname - имя, в столбце Lname - фамилия). Первичный ключ таблицы Director - dir_id - идентификационный номер режиссёра. Dir_id также - внешний ключ таблицы Play, он ссылается на первичный ключ таблицы Director. Требуется вывести спектакли режиссеров John Barton и Trevor Nunn.

Решение. Объединим результаты двух запросов - один возвращает спектакли режиссёра John Barton, другой - режиссёра Trevor Nunn. А каждый из этих объединяемых запросов к таблице Play делаем с подзапросом к таблице Director, который возвращает dir_id по имени и фамилии режиссёра. Каждый внешний запрос принимает из вложенного запроса значение ключа dir_id и возвращает названия постановок (Name):

SELECT NAME FROM PLAY WHERE dir_id = (SELECT dir_id FROM DIRECTOR WHERE fname = 'John' AND lname = 'Barton') UNION SELECT NAME FROM PLAY WHERE dir_id = (SELECT dir_id FROM DIRECTOR WHERE fname = 'Trevor' AND lname = 'Nunn')

Поделиться с друзьями

Другие темы в блоке "Реляционные базы данных"