UNION (Transact-SQL)

Kombiniert die Ergebnisse von mindestens zwei Abfragen zu einem Resultset, das alle Zeilen enthält, die zu allen Abfragen der Vereinigung gehören. Der UNION-Vorgang unterscheidet sich von dem Verwenden von Verknüpfungen, die Spalten aus zwei Tabellen kombinieren.

Für die Kombination der Resultsets von zwei Abfragen mit UNION gelten die folgenden Grundregeln:

  • Die Anzahl und die Reihenfolge von Spalten muss für alle Abfragen identisch sein.

  • Die Datentypen müssen kompatibel sein.

Themenlink (Symbol)Transact-SQL-Syntaxkonventionen

Syntax

    { <query_specification> | ( <query_expression> ) } 
    UNION [ ALL ] 
  <query_specification | ( <query_expression> ) 
 [ UNION [ ALL ] <query_specification> | ( <query_expression> ) 
    [ ...n ] ] 

Argumente

  • <query_specification> | ( <query_expression> )
    Dies ist eine Abfragespezifikation oder ein Abfrageausdruck, die bzw. der Daten zurückgibt, die mit den Daten aus einer anderen Abfragespezifikation oder einem anderen Abfrageausdruck zu kombinieren sind. Die Definitionen der Spalten, die Bestandteil eines UNION-Vorgangs sind, müssen nicht identisch, jedoch durch implizite Konvertierung kompatibel sein. Wenn sich die Datentypen unterscheiden, wird der Datentyp anhand der Regeln für die Rangfolge der Datentypen bestimmt. Wenn die Typen identisch sind, diese sich aber in der Genauigkeit, Dezimalstellenanzahl oder Länge unterscheiden, wird das Ergebnis auf Grundlage derselben Regeln wie für das Kombinieren von Ausdrücken bestimmt. Weitere Informationen finden Sie unter Genauigkeit, Dezimalstellen und Länge (Transact-SQL).

    Spalten vom Datentyp xml müssen identisch sein. Alle Spalten müssen entweder einen XML-Schematyp aufweisen oder nicht typisiert sein. Wenn sie typisiert sind, müssen sie derselben XML-Schemaauflistung zugeordnet werden.

  • UNION
    Gibt an, dass mehrere Resultsets kombiniert und als ein einzelnes Resultset zurückgegeben werden sollen.

  • ALL
    Bezieht alle Zeilen in das Ergebnis ein. Hierzu zählen auch Duplikate. Ohne diese Option werden doppelte Zeilen entfernt.

Beispiele

A. Verwenden einer einfachen UNION-Klausel

Das Resultset im folgenden Beispiel enthält den Inhalt der Spalten ProductModelID und Name der Tabellen ProductModel und 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

B. Verwenden von SELECT INTO mit UNION

Im folgenden Beispiel gibt die INTO-Klausel in der zweiten SELECT-Anweisung an, dass die ProductResults-Tabelle das endgültige Resultset der Union der angegebenen Spalten aus den Tabellen ProductModel und Gloves enthält. Beachten Sie, dass die Gloves-Tabelle in der ersten SELECT-Anweisung erstellt wird.

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. Verwenden von UNION in zwei SELECT-Anweisungen mit ORDER BY

Die Reihenfolge bestimmter Parameter, die mit der UNION-Klausel verwendet werden, ist von Bedeutung. Im folgenden Beispiel werden die richtige und die falsche Verwendung von UNION in zwei SELECT-Anweisungen veranschaulicht, in denen eine Spalte in der Ausgabe umbenannt werden soll.

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. Verwenden von UNION mit drei SELECT-Anweisungen, wobei die Auswirkung von ALL und Klammern gezeigt wird

In den folgenden Beispielen wird UNION verwendet, um die Ergebnisse aus drei Tabellen zu kombinieren, wobei in allen Tabellen 5 identische Datenzeilen vorhanden sind. Im ersten Beispiel wird UNION ALL verwendet, um doppelte Datensätze anzuzeigen, und alle 15 Zeilen zurückgegeben. Im zweiten Beispiel wird UNION ohne ALL verwendet, um die doppelten Zeilen aus den kombinierten Ergebnissen der drei SELECT-Anweisungen zu löschen. Es werden 5 Zeilen zurückgegeben.

Im dritten Beispiel wird ALL mit dem ersten UNION verwendet; das zweite UNION verwendet ALL nicht und ist in Klammern eingeschlossen. Da die zweite UNION-Anweisung in Klammern steht, wird sie zuerst verarbeitet; sie gibt 5 Zeilen zurück, weil die Option ALL nicht verwendet wird und Duplikate gelöscht werden. Diese 5 Zeilen werden mit den Ergebnissen der ersten SELECT-Anweisung mithilfe der UNION ALL-Schlüsselwörter kombiniert. Dabei werden die Duplikate in den beiden aus 5 Zeilen bestehenden Resultsets nicht entfernt. Das Endergebnis enthält 10 Zeilen.

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