共用方式為


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
    將所有資料列納入結果中。其中包括複本。若未指定,就會移除資料列複本。

範例

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