Операции с наборами позволяют объединить результаты нескольких запросов в один набор результатов. Операторы множества включают UNION
, INTERSECT
и EXCEPT
.
В SQL предложение UNION
объединяет результаты двух запросов SQL в единую таблицу всех совпадающих строк. Два запроса должны привести к одинаковому количеству столбцов и совместимых типов данных для объединения. Все повторяющиеся записи автоматически удаляются, если не используется UNION ALL
.
UNION
может быть полезен в приложениях хранилища данных, где таблицы не полностью нормализованы. Простым примером может служить база данных с таблицами sales2005
и sales2006
, которые имеют идентичные структуры, но разделены из соображений производительности. Запрос UNION
может объединять результаты из обеих таблиц.
Обратите внимание, что UNION ALL
не гарантирует порядок строк. Строки второго операнда могут появляться до, после или вместе со строками первого операнда. В ситуациях, когда требуется определенный порядок, необходимо использовать ORDER BY
.
Обратите внимание, что UNION ALL
может быть намного быстрее, чем простой UNION
.
Учитывая эти две таблицы:
person | сумма |
---|---|
Джо | 1000 |
Алекс | 2000 |
Боб | 5000 |
человек | amount |
---|---|
Joe | 2000 |
Alex | 2000 |
Zach | 35000 |
Выполнение этого оператора:
SELECT * FROM sales2005 UNION ВЫБРАТЬ * ИЗ sales2006;
дает этот набор результатов, хотя порядок строк может варьироваться, поскольку не было предоставлено предложение ORDER BY
:
person | amount |
---|---|
Joe | 1000 |
Алекс | 2000 |
Боб | 5000 |
Джо | 2000 |
Зак | 35000 |
Примечание что есть две строки для Джо, потому что эти строки различны по своим столбцам. Для Alex есть только одна строка, потому что эти строки не различны для обоих столбцов.
UNION ALL
дает разные результаты, потому что не удаляет дубликаты. Выполнение этого оператора:
SELECT * FROM sales2005 UNION ALL SELECT * FROM sales2006;
даст эти результаты, опять же с учетом разницы из-за отсутствия оператора ORDER BY
:
person | amount |
---|---|
Joe | 1000 |
Джо | 2000 |
Алекс | 2000 |
Алекс | 2000 |
Боб | 5000 |
Зак | 35000 |
В обсуждении полных внешних объединений также есть пример, в котором используется оператор UNION
.
Оператор SQL INTERSECT
принимает результаты двух запросов и возвращает только строки, которые появляются в обоих наборах результатов. В целях удаления дубликатов оператор INTERSECT
не различает NULL
. Оператор INTERSECT
удаляет повторяющиеся строки из окончательного набора результатов. Оператор INTERSECT ALL
не удаляет повторяющиеся строки из окончательного набора результатов, но если строка появляется X раз в первом запросе и Y раз во втором, она появится минимум (X, Y) раз в набор результатов.
Следующий пример запроса INTERSECT
возвращает все строки из таблицы Orders, где количество находится между 50 и 100.
SELECT * FROM Orders WHERE Quantity BETWEEN 1 И 100 ПЕРЕСЕЧЕНИЕ ВЫБРАТЬ * ИЗ заказов, ГДЕ КОЛИЧЕСТВО МЕЖДУ 50 И 200;
Оператор SQL EXCEPT
берет отдельные строки одного запроса и возвращает строки, которые не появляются во втором наборе результатов. В целях исключения строк и удаления дубликатов оператор EXCEPT
не различает NULL
. Оператор EXCEPT ALL
не удаляет дубликаты, но если строка появляется X раз в первом запросе и Y раз во втором, она будет отображаться в наборе результатов не более (X - Y, 0) раз.
В частности, платформа Oracle предоставляет оператор MINUS
, который функционально эквивалентен стандарту SQL EXCEPT DISTINCT
operator [1].
Следующий пример запроса EXCEPT
возвращает все строки из таблицы Orders, где количество находится в диапазоне от 1 до 49, и те, которые имеют количество от 76 до 100.
Другими словами; запрос возвращает все строки, в которых количество составляет от 1 до 100, за исключением строк, где количество находится в диапазоне от 50 до 75.
ВЫБРАТЬ * ИЗ заказов, ГДЕ КОЛИЧЕСТВО МЕЖДУ 1 И 100, ИСКЛЮЧАЯ ВЫБРАТЬ * ИЗ заказов, ГДЕ КОЛИЧЕСТВО МЕЖДУ 50 И 75 ;
Следующий пример эквивалентен приведенному выше, но без использования оператора EXCEPT
.
ВЫБРАТЬ o1. * ИЗ (ВЫБРАТЬ * ИЗ ЗАКАЗОВ, ГДЕ КОЛИЧЕСТВО МЕЖДУ 1 И 100) o1 ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ * ИЗ ЗАКАЗОВ, ГДЕ КОЛИЧЕСТВО МЕЖДУ 50 И 75) o2 НА o1.id = o2.id ГДЕ o2.id НУЛЕВО