UNION (Transact-SQL)
Объединяет результаты двух или более запросов в один результирующий набор, в который входят все строки, принадлежащие всем запросам в объединении. Операция UNION отличается от соединений столбцов из двух таблиц.
Ниже приведены основные правила объединения результирующих наборов двух запросов с помощью операции UNION:
- Количество и порядок столбцов должны быть одинаковыми во всех запросах.
- Тип данных должен быть совестимым.
Соглашения о синтаксическом обозначении в Transact-SQL
Синтаксис
{ <query_specification> | ( <query_expression> ) }
UNION [ ALL ]
<query_specification | ( <query_expression> )
[ UNION [ ALL ] <query_specification> | ( <query_expression> )
[ ...n ] ]
Аргументы
<query_specification> | ( <query_expression> )
Спецификация запроса или выражение запроса, возвращающее данные для объединения с данными из другой спецификации запроса или выражения запроса. Определения столбцов, которые являются частью операции UNION, не должны совпадать, однако должны быть совместимыми посредством неявного преобразования. Если типы данных различаются, то получившийся тип данных определяется на основе правил очередности типов данных. Если типы совпадают, но различаются в точности, масштабе или длине, результат определяется на основе правил, используемых для объединения выражений. Дополнительные сведения см. в разделе Точность, масштаб и длина (Transact-SQL).Столбцы типа данных xml должны быть эквивалентны. Все столбцы должны либо иметь тип, определенный в XML-схеме, либо быть нетипизированными. Типизированные столбцы должны относиться к одной и той же коллекции XML-схем.
- UNION
Указывает на то, что несколько результирующих наборов следует объединить и возвратить в виде единого результирующего набора.
- ALL
Объединяет в результирующий набор все строки. Это относится и к дублирующимся строкам. Если обратное не указано, дубликаты строк удаляются.
Примеры
А. Использование простого предложения UNION
При выполнении следующего примера в результирующий набор включается содержимое столбцов ProductModelID
и Name
таблиц ProductModel
и Gloves
.
USE AdventureWorks ;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves ;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4) ;
GO
-- Here is the simple union.
USE AdventureWorks ;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name ;
GO
Б. Использование инструкции SELECT INTO с предложением UNION
При выполнении следующего примера предложение INTO
во второй инструкции SELECT
указывает, что в таблице с именем ProductResults
содержится итоговый результирующий набор объединения заданных столбцов таблиц ProductModel
и Gloves
. Заметим, что таблица Gloves
была создана в результате выполнения первой инструкции SELECT
.
USE AdventureWorks ;
GO
IF OBJECT_ID ('dbo.ProductResults', 'U') IS NOT NULL
DROP TABLE dbo.ProductResults ;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves ;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4) ;
GO
USE AdventureWorks ;
GO
SELECT ProductModelID, Name
INTO ProductResults
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves ;
GO
SELECT *
FROM dbo.ProductResults ;
В. Использование предложения UNION для двух инструкций SELECT совместно с ORDER BY
При использовании предложения UNION необходимо соблюдать порядок следования определенных параметров. В следующем примере приведены случаи верного и неверного использования предложения UNION
с двумя инструкциями SELECT
, при котором выходные столбцы должны быть переименованы.
USE AdventureWorks ;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves ;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4) ;
GO
/* INCORRECT */
USE AdventureWorks ;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
ORDER BY Name
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves ;
GO
/* CORRECT */
USE AdventureWorks ;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name ;
GO
Г. Использование предложения UNION с тремя инструкциями SELECT и иллюстрация влияния скобок и ключевого слова ALL
В следующих примерах предложение UNION
используется для комбинирования результатов из трех таблиц, содержащих по 5 одинаковых строк данных. В первом примере используется предложение UNION ALL
, в результате чего выдаются все 15 строк. Во втором примере предложение UNION
используется без ключевого слова ALL
, что позволяет удалить повторяющиеся строки из комбинированного результата выполнения трех инструкций SELECT
и вывести только 5 строк.
В третьем примере с первым предложением ALL
используется ключевое словоUNION
, а во втором предложении UNION
вместо ключевого слова ALL
используются скобки. Сначала выполняется второе предложение UNION
, которое заключено в скобки. В результате возвращаются 5 строк, так как параметр ALL
не используется и все повторяющиеся строки удаляются. Полученные 5 строк совмещаются с результатами выполнения первой инструкции SELECT
с помощью ключевого слова UNION ALL
. В данном случае повторяющиеся строки двух множеств не удаляются. Окончательный результат состоит из 10 строк.
USE AdventureWorks ;
GO
IF OBJECT_ID ('EmployeeOne', 'U') IS NOT NULL
DROP TABLE EmployeeOne ;
GO
IF OBJECT_ID ('EmployeeTwo', 'U') IS NOT NULL
DROP TABLE EmployeeTwo ;
GO
IF OBJECT_ID ('EmployeeThree', 'U') IS NOT NULL
DROP TABLE EmployeeThree ;
GO
SELECT c.LastName, c.FirstName, e.Title
INTO EmployeeOne
FROM Person.Contact c JOIN HumanResources.Employee e
ON e.ContactID = c.ContactID
WHERE ManagerID = 66 ;
GO
SELECT c.LastName, c.FirstName, e.Title
INTO EmployeeTwo
FROM Person.Contact c JOIN HumanResources.Employee e
ON e.ContactID = c.ContactID
WHERE ManagerID = 66 ;
GO
SELECT c.LastName, c.FirstName, e.Title
INTO EmployeeThree
FROM Person.Contact c JOIN HumanResources.Employee e
ON e.ContactID = c.ContactID
WHERE ManagerID = 66 ;
GO
-- Union ALL
SELECT LastName, FirstName
FROM EmployeeOne
UNION ALL
SELECT LastName, FirstName
FROM EmployeeTwo
UNION ALL
SELECT LastName, FirstName
FROM EmployeeThree ;
GO
SELECT LastName, FirstName
FROM EmployeeOne
UNION
SELECT LastName, FirstName
FROM EmployeeTwo
UNION
SELECT LastName, FirstName
FROM EmployeeThree ;
GO
SELECT LastName, FirstName
FROM EmployeeOne
UNION ALL
(
SELECT LastName, FirstName
FROM EmployeeTwo
UNION
SELECT LastName, FirstName
FROM EmployeeThree
) ;
GO
См. также
Справочник
SELECT (Transact-SQL)
Примеры использования инструкции SELECT (Transact-SQL)