Как применять оператор SQL UNION для объединения результатов запросов
Назад<<< | Листать | Вперёд>>> |
Оператор языка SQL UNION предназначен для объединения результирующих таблиц базы данных, полученных с применением слова SELECT. Условие объединения результирующих таблиц: совпадение числа, порядка следования и типа данных столбцов. ORDER BY следует применять к результату объединения и размещать только в конце составного запроса. Оператор UNION имеет следующий синтаксис:
В этой конструкции объединяемые запросы могут иметь условия в секции WHERE, а могут не иметь их. При помощи оператора UNION можно объединить запросы на извлечение данных как из одной таблицы, так и из разных.
При использовании оператора UNION без слова ALL результат не содержит дубликатов, а со словом ALL - содержит дубликаты.
Итоги и индивидуальные значения в одной таблице с помощью оператора SQL UNION
Одним запросом можно вывести из таблицы индивидуальные значения столбцов, например, число лет, проработанных сотрудниками фирмы, размеры их заработной платы и другие. Другим запросом - с использованием агрегатных функций - можно получить, например, сумму заработных плат, получаемых сотрудниками отделов или занимающих те или иные должности, или среднее число лет трудового стажа (в таких запросах применяется группировка с помощью оператора GROUP BY).
А если нам требуется получить в одной таблице и сводку всех индивидуальных значений, и итоговые значения? Здесь на помощь приходит оператор SQL UNION, с помощью которого два запроса объединяются. К результату объединения требуется применить упорядочение, используя оператор ORDER BY. Для чего это необходимо, будет лучше понятно из примеров.
Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке.
Пример 1. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. В ней есть столбцы Salary (размер заработной платы), Job (должность) и Years (длительность трудового стажа). Первый запрос возвращает индивидуальные размеры заработной платы, упорядоченные по должностям:
Результатом выполнения запроса будет следующая таблица:
Name | Job | Salary |
Sanders | Mgr | 18357.5 |
Marenghi | Mgr | 17506.8 |
Pernal | Sales | 18171.2 |
Doctor | Sales | 12322.4 |
Factor | Sales | 16228.7 |
Второй запрос вернёт суммарную заработную плату по должностям. Мы уже готовим этот запрос для соединения с первым, поэтому будем помнить, что условием соединения является равное число столбцов, совпадение их названий, порядка следования и типов данных. Поэтому включаем в таблицу с итогами также столбец Name с произвольным значением 'Z-TOTAL':
Результатом выполнения запроса будет следующая таблица:
Name | Job | Salary |
Z-TOTAL | Mgr | 35864.3 |
Z-TOTAL | Sales | 46722.3 |
Теперь объединим запросы при помощи оператора UNION и применим оператору ORDER BY к результату объединения. Группировать следует по двум столбцам: должность (Job) и имя (Name), чтобы строки с итоговыми (суммарными) значениями, в которых значение имени - 'Z-TOTAL', находились ниже строк с индивидуальными значениями. Объединение результатов запросов будет следующим:
Результатом выполнения запроса с оператором UNION будет следующая таблица, в которой каждая первая строка в каждой группе должностей будет содержать суммарную заработную плату сотрудников, работающих на этой должности:
Name | Job | Salary |
Marenghi | Mgr | 17506.8 |
Sanders | Mgr | 18357.5 |
Z-TOTAL | Mgr | 35864.3 |
Doctor | Sales | 12322.4 |
Factor | Sales | 16228.7 |
Pernal | Sales | 18171.2 |
Z-TOTAL | Sales | 46722.3 |
Написать запросы с использованием UNION самостоятельно, а затем посмотреть решение
Пример 2. Данные - те же, что в примере 1, но задача немного посложнее. Требуется вывести в одной таблице не только индивидуальные размеры заработной платы, упорядоченные по должностям и суммарную заработную плату по должностям, но суммарную заработную плату по всем сотрудникам.
Пример 3. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. В ней есть столбцы Name (фамилия), Dept (номер отдела), и Years (длительность трудового стажа).
Name | Dept | Years |
Sanders | 20 | 7 |
Pernal | 20 | 8 |
Marenghi | 38 | 5 |
Doctor | 20 | 5 |
Factor | 38 | 8 |
Вывести в одной таблице средний трудовой стаж по отделам и индивидуальные значения длительности трудового стажа сотрудников, сгруппированных по номерам отделов.
Другие случаи объединения запросов к одной таблице с помощью оператора SQL UNION
Пример 4. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. В ней есть столбцы Salary (размер заработной платы), Job (должность) и Years (длительность трудового стажа). Первый запрос нужен для получения данных о сотрудниках, заработная плата которых более 21000:
Результатом выполнения запроса будет следующая таблица:
ID | Name |
140 | Fraye |
160 | Molinare |
260 | Jones |
Второй запрос возвращает имена сотрудников, должность которых "менеждер", а число лет трудового стажа - менее 8:
Результатом выполнения запроса будет следующая таблица:
ID | Name |
10 | Sanders |
30 | Marenghi |
100 | Plotz |
140 | Fraye |
160 | Molinare |
240 | Daniels |
Теперь требуются данные, в которых объединены критерии отбора, применённые в двух запросах. Объединяем запросы при помощи оператора UNION:
Результатом выполнения запроса с оператором UNION будет следующая таблица:
ID | Name |
10 | Sanders |
30 | Marenghi |
100 | Plotz |
140 | Fraye |
160 | Molinare |
240 | Daniels |
260 | Jones |
Запрос с оператором UNION может возвращать и большее количество столбцов, важно, повторимся, чтобы в объединяемых запросах число столбцов, порядок их следования и типы данных совпадали.
Теперь работаем с базой данных "Портал объявлений - 1". Скрипт для создания этой базы данных, её таблицы и заполения таблицы данных - в файле по этой ссылке
Пример 5. Есть база данных портала объявлений.
Пусть сначала требуется получить данные о категориях и частях категорий объявлений, в которых подано более 100 объявлений в неделю. Пишем следующий запрос:
Результатом выполнения запроса будет следующая таблица:
Category | Part | Units | Money |
Транспорт | Автомашины | 110 | 17600 |
Транспорт | Мотоциклы | 131 | 20960 |
Электротехника | Телевизоры | 127 | 8255 |
Электротехника | Холодильники | 137 | 8905 |
Стройматериалы | Регипс | 112 | 11760 |
Досуг | Музыка | 117 | 7605 |
Теперь требуется извлечь данные о категориях и частях категорий объявлений, за которые выручено более 10000 денежных единиц в неделю. Пишем следующий запрос:
Результатом выполнения запроса будет следующая таблица:
Category | Part | Units | Money |
Транспорт | Автомашины | 110 | 17600 |
Недвижимость | Квартиры | 89 | 18690 |
Недвижимость | Дачи | 57 | 11970 |
Транспорт | Мотоциклы | 131 | 20960 |
Стройматериалы | Регипс | 112 | 11760 |
Теперь требуется извлечь данные, которые соответствуют критериям и первого, и второго запросов. Объединяем запросы при помощи оператора UNION:
Результатом выполнения запроса будет следующая таблица:
Транспорт | Автомашины | 110 | 17600 |
Транспорт | Мотоциклы | 131 | 20960 |
Недвижимость | Квартиры | 89 | 18690 |
Недвижимость | Дачи | 57 | 11970 |
Электротехника | Телевизоры | 127 | 8255 |
Электротехника | Холодильники | 137 | 8905 |
Стройматериалы | Регипс | 112 | 11760 |
Досуг | Музыка | 117 | 7605 |
Примеры запросов к базе данных "Портал объявлений-1" есть также в уроках об операторах INSERT, UPDATE, DELETE, HAVING.
Объединение результатов запросов к двум таблицам с помощью оператора SQL UNION
До сих пор мы рассматривали запросы с оператором UNION, в которых объединялись результаты из одной таблицы. Теперь будем объединять результаты из двух таблиц.
Пример 6. Есть база данных склада строительных материалов. В ней есть таблицы, содержащая данные об обоях. Таблица Vinil содержит данные о виниловых обоях, таблица Paper - о бумажных обоях. Требуется узнать данные о ценах обоев из одной и другой таблицы.
Чтобы извлечь не повторяющиеся данные о ценах на виниловые обои, составим запрос со словом DISTINCT:
Результатом выполнения запроса будет следующая таблица:
Price |
400 |
500 |
530 |
610 |
720 |
800 |
850 |
Чтобы извлечь не повторяющиеся данные о ценах на бумажные обои, составим следующий запрос, также со словом DISTINCT:
Результатом выполнения запроса будет следующая таблица:
Price |
300 |
320 |
360 |
400 |
430 |
500 |
530 |
Теперь составим объединённый запрос с оператором UNION:
Так как мы не используем слово ALL, дубликаты значений 400, 500 и 530 выводиться не будут. Результатом выполнения запроса будет следующая таблица:
Price |
300 |
320 |
360 |
400 |
430 |
500 |
530 |
610 |
720 |
800 |
850 |
Пример 7. База данных и таблицы - те же, что и в предыдущем примере.
Требуется получить все данные о ценах, в том числе повторяющиеся. Запрос на объединение результатов с использованием оператора UNION будет аналогичен запросу в предыдущем примере, но вместо просто UNION пишем UNION ALL:
Результатом выполнения запроса будет следующая таблица:
Price |
300 |
320 |
360 |
400 |
400 |
430 |
500 |
500 |
530 |
530 |
610 |
720 |
800 |
850 |
При помощи оператора SQL UNION можно объединить как простые запросы, так и запросы, содержащие подзапросы (вложенные запросы). Рассмотрим соответствующий пример.
Пример 8. Есть база данных "Театр". В её таблице 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):
Поделиться с друзьями
Назад<<< | Листать | Вперёд>>> |