Union (SQL)

В языке SQL операция UNION применяется для объединения двух наборов строк, возвращаемых SQL-запросами. Оба запроса должны возвращать одинаковое число столбцов, и столбцы с одинаковым порядковым номером должны иметь совместимые типы данных. Результат получает структуру (названия и типы столбцов) первого (левого) запроса, то есть операция не является симметричной.

При объединении нескольких запросов подряд результат последовательно вычисляется слева направо.

Данный оператор был описан в первом стандарте SQL — SQL/89[1].

Синтаксис

Оператор указывается между запросами. В упрощенном виде это выглядит следующим образом:

<запрос1>
UNION [ALL]
<запрос2>
UNION [ALL]
<запрос3>
 .....;

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

Необходимо отметить, что UNION сам по себе не гарантирует порядок строк. Строки из второго запроса могут оказаться в начале, в конце или вообще перемешаться со строками из первого запроса. В случаях, когда требуется определенный порядок, необходимо использовать выражение ORDER BY.

Правила использования

Существуют два основных правила, регламентирующие порядок использования оператора UNION:

  • число и порядок извлекаемых столбцов должны совпадать во всех объединяемых запросах;
  • типы данных в соответствующих столбцах должны быть совместимы.

Типы данных столбцов, данные из которых извлекаются в объединяемых запросах, не обязательно должны полностью совпадать, однако должны быть совместимыми путём неявного преобразования. Если типы данных различаются, то получившийся тип данных определяется на основе правил очередности типов данных (для конкретной СУБД). Если типы совпадают, но различаются в точности, масштабе или длине, результат определяется на основе правил, используемых для объединения выражений (для конкретной СУБД)[2]. Типы не определенные ANSI, такие как DATA и BINARY, обычно должны совпадать с другими столбцами такого же нестандартного типа[3].

В Microsoft SQL Server столбцы с типом данных XML должны быть эквивалентными. Все столбцы должны либо иметь тип, определенный в XML-схеме, либо быть нетипизированными. Типизированные столбцы должны относиться к одной и той же коллекции XML-схем[2].

Ещё одно ограничение на совместимость — это запрет пустых значений (NULL) в любом столбце объединения, причем эти значения необходимо запретить и для всех соответствующих столбцов в других запросах объединения, поскольку пустые значения (NULL) запрещены с ограничением NOT NULL. Кроме того, нельзя использовать UNION в подзапросах, а также нельзя использовать агрегатные функции в предложении SELECT запроса в объединении (однако большинство СУБД пренебрегают этими ограничениями)[3].

Применение

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

Также стоит отметить, что UNION ALL работает быстрее, чем просто UNION, поскольку по умолчанию при использовании оператора UNION дополнительно проводится устранение дубликатов, а при использовании UNION ALL — нет[4].

Примеры

Использование UNION при выборке из двух таблиц

Даны две таблицы:

sales2005
person amount
Иван 1000
Алексей 2000
Сергей 5000
sales2006
person amount
Иван 2000
Алексей 2000
Петр 35000

При выполнении следующего запроса:

(SELECT * FROM sales2005)
UNION
(SELECT * FROM sales2006);

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

person amount
Иван 1000
Алексей 2000
Иван 2000
Сергей 5000
Петр 35000

В результате отобразятся две строки с Иваном, так как эти строки различаются значениями в столбцах. Но при этом в результате присутствует лишь одна строка с Алексеем, поскольку значения в столбцах полностью совпадают.

Использование UNION ALL при выборке из двух таблиц

Применение UNION ALL дает другой результат, так как дубликаты не скрываются. Выполнение запроса:

(SELECT * FROM sales2005)
UNION ALL
(SELECT * FROM sales2006);

даст следующий результат, выводимый без упорядочивания ввиду отсутствия выражения ORDER BY:

person amount
Иван 1000
Иван 2000
Алексей 2000
Алексей 2000
Сергей 5000
Петр 35000

Использование UNION при выборке из одной таблицы

Аналогичным образом можно объединять два разных запроса из одной и той же таблицы (хотя вместо этого, как правило, необходимые параметры комбинируют в одном запросе при помощи ключевых слов AND и OR в условии WHERE):

(SELECT person, amount FROM sales2005 WHERE amount=1000)
UNION
(SELECT person, amount FROM sales2005 WHERE person like 'Сергей');

В результате получится:

person amount
Иван 1000
Сергей 5000

Использование UNION как внешнее объединение

При помощи UNION можно создавать также полные внешние объединения (иногда используется в случае отсутствия встроенной прямой поддержки внешних объединений):

(SELECT *
FROM   employee 
       LEFT JOIN department 
          ON employee.DepartmentID = department.DepartmentID)
UNION
(SELECT *
FROM   employee
       RIGHT JOIN department
          ON employee.DepartmentID = department.DepartmentID);

Но при этом необходимо помнить, что это все же не одно и то же, что и оператор JOIN.

См. также

Примечания

  1. Язык баз данных SQL/89 Архивная копия от 2 декабря 2018 на Wayback Machine  (рус.)
  2. 1 2 UNION (Transact-SQL) Архивная копия от 23 сентября 2010 на Wayback Machine  (рус.)
  3. 1 2 Использование предложения UNION Архивная копия от 9 февраля 2010 на Wayback Machine  (рус.)
  4. Оптимизация запросов Архивная копия от 14 апреля 2009 на Wayback Machine  (рус.)

Пункт 4 - нерабочая ссылка (на 08.11.2012)

Ссылки

Общее описание
  • Понимание SQL. Глава 14. Использование предложения UNION Архивная копия от 9 февраля 2010 на Wayback Machine  (рус.)
  • SQL UNION Operator Архивная копия от 7 октября 2010 на Wayback Machine  (англ.)
  • UNION (DISTINCT) and UNION ALL Архивная копия от 5 января 2011 на Wayback Machine  (англ.)
Реализация в MS SQL Server
  • Описание UNION (Transact-SQL) в MSDN Архивная копия от 23 сентября 2010 на Wayback Machine  (рус.)
Реализация в MySQL
  • Querying data by using SQL UNION Архивная копия от 27 июля 2011 на Wayback Machine (примеры использования в MySQL)  (англ.)
  • UNION Syntax Архивная копия от 13 ноября 2010 на Wayback Machine (в MySQL)  (англ.)
Реализация в PostgreSQL
  • UNION Clause Архивная копия от 9 марта 2018 на Wayback Machine (в PostgreSQL)  (англ.)
Реализация в Oracle
  • The UNION (ALL), INTERSECT, MINUS Operators Архивная копия от 20 мая 2011 на Wayback Machine  (англ.)
Реализация в Informix
  • Compose advanced SELECT statements  (англ.)
Перейти к шаблону «SQL»
SQL
Версии
  • SQL-86
  • SQL-89
  • SQL-92
  • SQL:1999
  • SQL:2003
  • SQL:2006
  • SQL:2008
  • SQL:2011
  • SQL:2016
Ключевые слова
  • Alter
  • As
  • Case
  • Create
  • Delete
  • From
  • Insert
  • Join
  • Merge
  • Null
  • Prepare
  • Select
  • Truncate
  • Union
  • Update
  • Where
  • With
Связанные статьи
Части ISO/IEC SQL
Перейти к шаблону «Базы данных»
Концепции
Объекты
Ключи
Компоненты
SQL
DML
  • SELECT
  • INSERT
  • UPDATE
  • DELETE
  • MERGE
DDL
  • CREATE
  • ALTER
  • DROP
  • TRUNCATE
DCL