Операции над множествами SQL¶
Операции над множествами SQL — это группа операторов языка SQL, предназначенная для объединения результатов двух или более запросов SELECT в единый результирующий набор. В отличие от соединений (JOIN), которые объединяют столбцы разных таблиц по условию, операции над множествами работают со строками: они сравнивают полные наборы строк, возвращаемые каждым запросом, и формируют новый набор на основе теоретико-множественных принципов (объединение, пересечение, разность). Основными операторами являются UNION, INTERSECT и EXCEPT (в некоторых СУБД — MINUS).
¶Основные принципы
Для корректного выполнения любой операции над множествами оба запроса SELECT должны удовлетворять следующим требованиям:
- Одинаковое количество столбцов в каждом запросе.
- Совместимость типов данных соответствующих столбцов по позиции (необязательно идентичные типы, но допускающие неявное или явное приведение).
- Одинаковый порядок сортировки (если используется
ORDER BY, он применяется к конечному результату, а не к отдельным запросам).
Результат операции не содержит дублирующихся строк по умолчанию, если не указано ключевое слово ALL.
¶Оператор UNION
UNION (объединение) возвращает все уникальные строки, которые присутствуют хотя бы в одном из двух запросов. Если строка встречается в обоих запросах, в результат она включается один раз.
Синтаксис: ``sql SELECT столбцы FROM таблица1 UNION [ALL] SELECT столбцы FROM таблица2; ``
UNION(безALL) — удаляет дубликаты, выполняя сортировку результатов. Это может замедлить выполнение на больших объёмах данных.UNION ALL— возвращает все строки из обоих запросов, включая дубликаты. Выполняется быстрее, так как не требует дополнительной сортировки и сравнения.
Пример. Получить список всех городов, где живут клиенты или сотрудники: ``sql SELECT City FROM Customers UNION SELECT City FROM Employees; ``
¶Оператор INTERSECT
INTERSECT (пересечение) возвращает только те строки, которые присутствуют одновременно в результатах обоих запросов. Дубликаты удаляются.
Синтаксис: ``sql SELECT столбцы FROM таблица1 INTERSECT SELECT столбцы FROM таблица2; ``
Пример. Найти города, в которых есть и клиенты, и сотрудники: ``sql SELECT City FROM Customers INTERSECT SELECT City FROM Employees; ``
¶Оператор EXCEPT (MINUS)
EXCEPT (разность) возвращает строки, которые присутствуют в результате первого запроса, но отсутствуют в результате второго. В СУБД Oracle вместо EXCEPT используется оператор MINUS.
Синтаксис: ``sql SELECT столбцы FROM таблица1 EXCEPT SELECT столбцы FROM таблица2; ``
Пример. Получить города, где есть клиенты, но нет сотрудников: ``sql SELECT City FROM Customers EXCEPT SELECT City FROM Employees; ``
¶Ключевое слово ALL
Использование ALL с операторами UNION, INTERSECT и EXCEPT изменяет поведение при работе с дубликатами:
UNION ALL— сохраняет все дубликаты.INTERSECT ALL— возвращает строки, количество повторений которых в первом запросе равно количеству во втором (или меньше, если дубликатов во втором меньше). Поддерживается не всеми СУБД (например, в PostgreSQL поддерживается, в MySQL — нет).EXCEPT ALL— возвращает строки из первого запроса, вычитая количество их вхождений во втором запросе. Поддерживается не всеми СУБД.
¶Порядок выполнения и приоритет
Операции над множествами выполняются последовательно сверху вниз, если не используются скобки. Приоритет операторов не стандартизирован, поэтому для явного управления порядком рекомендуется использовать круглые скобки ().
``sql -- Сначала выполнится INTERSECT, затем UNION (SELECT City FROM Customers INTERSECT SELECT City FROM Suppliers) UNION SELECT City FROM Employees; ``
¶Использование ORDER BY
Оператор ORDER BY применяется к конечному результату всей операции и указывается после последнего запроса. Имена столбцов в ORDER BY должны соответствовать именам столбцов из первого запроса (или можно использовать порядковые номера столбцов).
``sql SELECT City, COUNT() AS cnt FROM Customers GROUP BY City UNION SELECT City, COUNT() FROM Employees GROUP BY City ORDER BY cnt DESC; ``
¶Особенности в различных СУБД
- PostgreSQL: Полноценно поддерживает
UNION,INTERSECT,EXCEPTи их варианты сALL. - MySQL: Поддерживает только
UNIONиUNION ALL.INTERSECTиEXCEPTне реализованы; их можно эмулировать с помощью подзапросов иIN/NOT INилиEXISTS. - Microsoft SQL Server: Поддерживает
UNION,INTERSECT,EXCEPT. Варианты сALLдляINTERSECTиEXCEPTне поддерживаются. - Oracle Database: Использует
MINUSвместоEXCEPT. ПоддерживаетUNION,UNION ALL,INTERSECT,MINUS. Варианты сALLдляINTERSECTиMINUSне поддерживаются. - SQLite: Поддерживает
UNION,UNION ALL,INTERSECT,EXCEPT.
¶Отличия от соединений (JOIN)
Операции над множествами и соединения решают разные задачи:
| Характеристика | Операции над множествами | Соединения (JOIN) |
|---|---|---|
| Оперируют | Строками (вертикальное объединение) | Столбцами (горизонтальное объединение) |
| Условие | Строки сравниваются целиком по всем столбцам | Строки связываются по условию (обычно по ключу) |
| Количество столбцов | Должно быть одинаковым в обоих запросах | Может различаться |
| Результат | Новый набор строк | Новая таблица с объединёнными столбцами |
¶Примеры практического применения
- Объединение данных из разных источников: свести в один отчёт данные по продажам из нескольких филиалов, имеющих одинаковую структуру таблиц.
- Поиск пересечений: найти клиентов, которые одновременно являются поставщиками (используя
INTERSECTна таблицах с идентификаторами). - Выявление расхождений: определить товары, которые есть на складе, но отсутствуют в прайс-листе (используя
EXCEPT). - Формирование справочников: создать единый список городов или стран из нескольких таблиц без дубликатов.
¶Производительность
Операции над множествами, особенно UNION (без ALL), могут быть ресурсоёмкими из-за необходимости сортировки для удаления дубликатов. Для повышения производительности рекомендуется:
- Использовать
UNION ALLвместоUNION, если дубликаты не критичны. - Минимизировать количество обрабатываемых строк с помощью условий
WHEREв каждом запросе. - Использовать индексы на столбцах, участвующих в выборке.
¶Источники
- ISO/IEC 9075:2016 (SQL:2016) — стандарт языка SQL.
- Документация PostgreSQL: «UNION, INTERSECT, EXCEPT».
- Документация MySQL: «UNION Clause».
- Документация Microsoft SQL Server: «Set Operators (Transact-SQL)».
- Документация Oracle Database: «Set Operators».
