UNION (Transact-SQL)
將兩個或更多查詢的結果結合成單一結果集,其中包括屬於聯集中之所有查詢的所有資料列。UNION 作業不同於利用聯結來結合兩份資料表的資料行。
以下是利用 UNION 來組合兩項查詢的結果集之基本規則:
在所有查詢中,資料行的數目和順序都必須相同。
資料類型必須相容。
語法
{ <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
將所有資料列納入結果中。其中包括複本。若未指定,就會移除資料列複本。
範例
A. 使用簡單 UNION
在下列範例中,結果集包括 ProductModel 和 Gloves 資料表之 ProductModelID 和 Name 資料行的內容。
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
B. 搭配 UNION 使用 SELECT INTO
在下列範例中,第二個 SELECT 陳述式中的 INTO 子句指定利用名稱為 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 dbo.ProductResults
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves;
GO
SELECT *
FROM dbo.ProductResults;
C. 搭配 ORDER BY 使用兩個 SELECT 陳述式的 UNION
搭配 UNION 子句使用之特定參數的順序非常重要。下列範例會顯示在兩個 SELECT 陳述式中的輸出重新命名一個資料行時,UNION 的正確和不正確用法。
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
D. 利用三個 SELECT 陳述式的 UNION 來顯示 ALL 和括號的作用
下列範例會利用 UNION 來結合有 5 個相同資料列的三份資料表的結果。第一個範例利用 UNION ALL 來顯示重複的記錄,以及傳回所有的 15 個資料列。第二個範例利用不含 ALL 的 UNION 來刪除三個 SELECT 陳述式之組合結果中重複的資料列,並傳回 5 個資料列。
第三個範例搭配第一個 UNION 來使用 ALL,用括號括住未使用 ALL 的第二個 UNION。第二個 UNION 會先處理,因為它在括號中,且會傳回 5 個資料列,因為並未使用 ALL 選項,複本會移除。這 5 個資料列利用 SELECT 關鍵字,與第一個 UNION ALL 的結果結合起來。這並不會在兩組 5 個資料列之間移除複本。最終結果有 10 個資料列。
USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.EmployeeOne', 'U') IS NOT NULL
DROP TABLE EmployeeOne;
GO
IF OBJECT_ID ('dbo.EmployeeTwo', 'U') IS NOT NULL
DROP TABLE EmployeeTwo;
GO
IF OBJECT_ID ('dbo.EmployeeThree', 'U') IS NOT NULL
DROP TABLE EmployeeThree;
GO
SELECT c.LastName, c.FirstName, e.Title
INTO dbo.EmployeeOne
FROM Person.Contact AS c JOIN HumanResources.Employee AS e
ON e.ContactID = c.ContactID
WHERE ManagerID = 66;
GO
SELECT c.LastName, c.FirstName, e.Title
INTO dbo.EmployeeTwo
FROM Person.Contact AS c JOIN HumanResources.Employee AS e
ON e.ContactID = c.ContactID
WHERE ManagerID = 66;
GO
SELECT c.LastName, c.FirstName, e.Title
INTO dbo.EmployeeThree
FROM Person.Contact AS c JOIN HumanResources.Employee AS e
ON e.ContactID = c.ContactID
WHERE ManagerID = 66;
GO
-- Union ALL
SELECT LastName, FirstName
FROM dbo.EmployeeOne
UNION ALL
SELECT LastName, FirstName
FROM dbo.EmployeeTwo
UNION ALL
SELECT LastName, FirstName
FROM dbo.EmployeeThree;
GO
SELECT LastName, FirstName
FROM dbo.EmployeeOne
UNION
SELECT LastName, FirstName
FROM dbo.EmployeeTwo
UNION
SELECT LastName, FirstName
FROM dbo.EmployeeThree;
GO
SELECT LastName, FirstName
FROM dbo.EmployeeOne
UNION ALL
(
SELECT LastName, FirstName
FROM dbo.EmployeeTwo
UNION
SELECT LastName, FirstName
FROM dbo.EmployeeThree
);
GO