UNION (Transact-SQL)

複数のクエリの結果を、1 つの結果セットに結合します。すべてのクエリの結果セットに含まれるすべての行は、その共用体に含まれます。これは、2 つのテーブルの列を結合した結合列とは異なります。

UNION を使用して 2 つのクエリの結果セットを結合するための基本的な規則を以下に示します。

  • 列の数と順番は、すべてのクエリで同じでなければなりません。

  • データ型が一致していなければなりません。

トピック リンク アイコン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
    複数の結果セットを結合し、1 つの結果セットとして返すことを指定します。

  • ALL
    すべての行が結果セットに含まれます。これには、重複した行も含まれます。指定しない場合、重複する行は削除されます。

A. 単純な UNION を使用する

次の例では、結果セットに ProductModel テーブルと Gloves テーブルの ProductModelID 列と Name 列の内容が含まれています。

USE AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 を使用する

この例では、2 番目の SELECT ステートメントの INTO 句で、ProductModel および Gloves テーブルの指定された列のユニオンの最終的な結果セットを ProductResults という名前のテーブルに格納することを指定します。Gloves テーブルは、最初の SELECT ステートメントで作成されます。

USE AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 句を指定した 2 つの SELECT ステートメントで UNION 句を使用する

UNION 句で使用するある種のパラメータの順序には重要な意味があります。次の例では、出力時に列名を変更する 2 つの SELECT ステートメントでの UNION の誤った使用法と正しい使用法を示しています。

USE AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 AdventureWorks2008R2;
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. 3 つの SELECT ステートメントで UNION を使用して、ALL とかっこの効果を示す

次の例では、UNION を使用して 3 つのテーブルのクエリ結果を結合します。これらのテーブルはすべて同じ 5 行のデータで構成されます。最初の例では、UNION ALL を使用して、重複するレコードも含めて 15 行すべてを返します。2 番目の例では、ALL を指定せずに UNION を使用して、3 つの SELECT ステートメントの結果を結合したものから重複する行を削除し、5 行を返します。

3 番目の例では、最初の UNION と共に ALL を使用し、ALL を使用していない 2 番目の UNION をかっこで囲んでいます。2 番目の UNION はかっこで囲まれているので、最初に処理されます。また、ALL オプションを使用せずに重複を削除するので、5 行を返します。これらの 5 行は、UNION ALL キーワードを使用して最初の SELECT の結果と結合されます。これによって 2 組の 5 行の間での重複が削除されることはありません。最終的な結果は 10 行になります。

USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('dbo.EmployeeOne', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeOne;
GO
IF OBJECT_ID ('dbo.EmployeeTwo', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeTwo;
GO
IF OBJECT_ID ('dbo.EmployeeThree', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeThree;
GO

SELECT pp.LastName, pp.FirstName, e.JobTitle 
INTO dbo.EmployeeOne
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle 
INTO dbo.EmployeeTwo
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle 
INTO dbo.EmployeeThree
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
-- Union ALL
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeOne
UNION ALL
SELECT LastName, FirstName ,JobTitle
FROM dbo.EmployeeTwo
UNION ALL
SELECT LastName, FirstName,JobTitle 
FROM dbo.EmployeeThree;
GO

SELECT LastName, FirstName,JobTitle
FROM dbo.EmployeeOne
UNION 
SELECT LastName, FirstName, JobTitle 
FROM dbo.EmployeeTwo
UNION 
SELECT LastName, FirstName, JobTitle 
FROM dbo.EmployeeThree;
GO

SELECT LastName, FirstName,JobTitle 
FROM dbo.EmployeeOne
UNION ALL
(
SELECT LastName, FirstName, JobTitle 
FROM dbo.EmployeeTwo
UNION
SELECT LastName, FirstName, JobTitle 
FROM dbo.EmployeeThree
);
GO