SELECT-Beispiele (Transact-SQL)

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL verwaltete Instanz

In diesem Artikel werden Beispiele für die Verwendung der SELECT-Anweisung bereitgestellt.

Die Transact-SQL-Codebeispiele in diesem Artikel verwenden die AdventureWorks2022- oder AdventureWorksDW2022-Beispieldatenbank, die Sie von der Homepage Microsoft SQL Server Samples and Community Projects herunterladen können.

A. SELECT zum Abrufen von Zeilen und Spalten verwenden

Im folgenden Beispiel werden drei Codebeispiele aufgeführt. Im ersten Codebeispiel werden alle Zeilen (es ist keine WHERE-Klausel angegeben) und alle Spalten (mit *) aus der Product-Tabelle in der AdventureWorks2022-Datenbank zurückgegeben.

USE AdventureWorks2022;
GO

SELECT *
FROM Production.Product
ORDER BY Name ASC;

-- Alternate way.
USE AdventureWorks2022;
GO

SELECT p.*
FROM Production.Product AS p
ORDER BY Name ASC;
GO

In diesem Beispiel werden alle Zeilen (keine WHERE-Klausel angegeben) und nur eine Teilmenge der Spalten (Name, ProductNumber, ListPrice) aus der Product-Tabelle in der AdventureWorks2022-Datenbank zurückgegeben. Außerdem werden Spaltenüberschriften hinzugefügt.

USE AdventureWorks2022;
GO

SELECT Name,
    ProductNumber,
    ListPrice AS Price
FROM Production.Product
ORDER BY Name ASC;
GO

In diesem Beispiel werden nur die Zeilen für Product zurückgegeben, die über die Produktgruppe R verfügen und für die die Anzahl von Fertigungstagen weniger als 4 beträgt.

USE AdventureWorks2022;
GO

SELECT Name,
    ProductNumber,
    ListPrice AS Price
FROM Production.Product
WHERE ProductLine = 'R'
    AND DaysToManufacture < 4
ORDER BY Name ASC;
GO

B. SELECT mit Spaltenüberschriften und Berechnungen verwenden

In diesen Beispielen werden alle Zeilen aus der Product-Tabelle zurückgegeben. Im ersten Beispiel werden die Gesamtumsatzzahlen und die Rabatte für jedes Produkt zurückgegeben. Im zweiten Beispiel werden die gesamten Einnahmen für jedes Produkt berechnet.

USE AdventureWorks2022;
GO

SELECT p.Name AS ProductName,
    NonDiscountSales = (OrderQty * UnitPrice),
    Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID
ORDER BY ProductName DESC;
GO

Diese Abfrage berechnet die Einnahmen für jedes Produkt in dem jeweiligen Kaufauftrag.

USE AdventureWorks2022;
GO

SELECT 'Total income is',
    ((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)),
    ' for ',
    p.Name AS ProductName
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID
ORDER BY ProductName ASC;
GO

C. DISTINCT mit SELECT verwenden

Im folgenden Beispiel wird DISTINCT verwendet, um das Abrufen von doppelten Titeln zu verhindern.

USE AdventureWorks2022;
GO

SELECT DISTINCT JobTitle
FROM HumanResources.Employee
ORDER BY JobTitle;
GO

D: Tabellen mit SELECT INTO erstellen

Im ersten Beispiel wird eine temporäre Tabelle namens #Bicycles in tempdb erstellt.

USE tempdb;
GO

IF OBJECT_ID(N'#Bicycles', N'U') IS NOT NULL
DROP TABLE #Bicycles;
GO

SELECT *
INTO #Bicycles
FROM AdventureWorks2022.Production.Product
WHERE ProductNumber LIKE 'BK%';
GO

In diesem zweiten Beispiel wird eine dauerhafte Tabelle namens NewProducts erstellt.

USE AdventureWorks2022;
GO

IF OBJECT_ID('dbo.NewProducts', 'U') IS NOT NULL
DROP TABLE dbo.NewProducts;
GO

ALTER DATABASE AdventureWorks2022 SET RECOVERY BULK_LOGGED;
GO

SELECT *
INTO dbo.NewProducts
FROM Production.Product
WHERE ListPrice > $25
    AND ListPrice < $100;
GO

ALTER DATABASE AdventureWorks2022 SET RECOVERY FULL;
GO

E. Korrelierte Unterabfragen verwenden

Eine korrelierte Unterabfrage ist eine Abfrage, die von der äußeren Abfrage abhängig ist. Die Abfrage kann wiederholt ausgeführt werden, und zwar einmal für jede Zeile, die von der äußeren Abfrage ausgewählt wird.

Im ersten Beispiel werden Abfragen gezeigt, die semantisch ähnlich sind, um den Unterschied zwischen der Verwendung des EXISTS-Schlüsselworts und des IN-Schlüsselworts zu veranschaulichen. In beiden Fällen handelt es sich um eine gültige Unterabfrage, die eine Instanz von jedem Produktnamen abruft, für den als Produktmodell ein langärmeliges Logo-T-Shirt angegeben ist und für den die ProductModelID-Nummern in den Product- und ProductModel-Tabellen übereinstimmen.

USE AdventureWorks2022;
GO

SELECT DISTINCT Name
FROM Production.Product AS p
WHERE EXISTS (
    SELECT *
    FROM Production.ProductModel AS pm
    WHERE p.ProductModelID = pm.ProductModelID
        AND pm.Name LIKE 'Long-Sleeve Logo Jersey%'
);
GO

-- OR
USE AdventureWorks2022;
GO

SELECT DISTINCT Name
FROM Production.Product
WHERE ProductModelID IN (
    SELECT ProductModelID
    FROM Production.ProductModel AS pm
    WHERE p.ProductModelID = pm.ProductModelID
        AND Name LIKE 'Long-Sleeve Logo Jersey%'
);
GO

Im nächsten Beispiel wird IN verwendet und eine Instanz des Vor- und Nachnamens der einzelnen Mitarbeiter abgerufen, für die der Bonus in der Tabelle SalesPerson5000.00 beträgt und für die die Mitarbeiter-IDs in den Tabellen Employee und SalesPerson übereinstimmen.

USE AdventureWorks2022;
GO

SELECT DISTINCT p.LastName,
    p.FirstName
FROM Person.Person AS p
INNER JOIN HumanResources.Employee AS e
    ON e.BusinessEntityID = p.BusinessEntityID
WHERE 5000.00 IN (
    SELECT Bonus
    FROM Sales.SalesPerson AS sp
    WHERE e.BusinessEntityID = sp.BusinessEntityID
);
GO

Die vorherige Unterabfrage in dieser Anweisung kann nicht unabhängig von der äußeren Abfrage ausgewertet werden. Sie benötigt einen Wert für Employee.EmployeeID, wobei sich dieser Wert ändert, wenn die SQL Server-Datenbank-Engine unterschiedliche Zeilen in Employee untersucht.

Eine abhängige Unterabfrage kann auch in der HAVING-Klausel einer äußeren Abfrage verwendet werden. Mit diesem Beispiel können Sie die Produktmodelle ermitteln, bei denen der maximale Listenpreis mehr als doppelt so hoch ist wie der Durchschnittpreis für das Modell.

USE AdventureWorks2022;
GO

SELECT p1.ProductModelID
FROM Production.Product AS p1
GROUP BY p1.ProductModelID
HAVING MAX(p1.ListPrice) >= (
    SELECT AVG(p2.ListPrice) * 2
    FROM Production.Product AS p2
    WHERE p1.ProductModelID = p2.ProductModelID
);
GO

In diesem Beispiel werden zwei abhängige Unterabfragen verwendet, um die Namen von Mitarbeitern zu finden, die ein bestimmtes Produkt verkauft haben.

USE AdventureWorks2022;
GO

SELECT DISTINCT pp.LastName,
    pp.FirstName
FROM Person.Person pp
INNER JOIN HumanResources.Employee e
    ON e.BusinessEntityID = pp.BusinessEntityID
WHERE pp.BusinessEntityID IN (
    SELECT SalesPersonID
    FROM Sales.SalesOrderHeader
    WHERE SalesOrderID IN (
        SELECT SalesOrderID
        FROM Sales.SalesOrderDetail
        WHERE ProductID IN (
            SELECT ProductID
            FROM Production.Product p
            WHERE ProductNumber = 'BK-M68B-42'
        )
    )
);
GO

F. GROUP BY verwenden

Im folgenden Beispiel wird die jeweilige Summe der einzelnen Kaufaufträge in der Datenbank ermittelt.

USE AdventureWorks2022;
GO

SELECT SalesOrderID,
    SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID
ORDER BY SalesOrderID;
GO

Wegen der GROUP BY-Klausel wird für jede Bestellung nur eine Zeile zurückgegeben, die die Summe aller Kaufaufträge enthält.

G. GROUP BY mit mehreren Gruppen verwenden

Dieses Beispiel ermittelt den Durchschnittspreis und die Summe der Jahr-bis-heute-Verkäufe, die nach Produkt-ID und Sonderangebots-ID gruppiert sind:

USE AdventureWorks2022;
GO

SELECT ProductID,
    SpecialOfferID,
    AVG(UnitPrice) AS [Average Price],
    SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY ProductID,
    SpecialOfferID
ORDER BY ProductID;
GO

H. GROUP BY und WHERE verwenden

In diesem Beispiel werden die Ergebnisse in Gruppen zusammengefasst, nachdem nur die Zeilen mit Listenpreisen von mehr als $1000 abgerufen wurden.

USE AdventureWorks2022;
GO

SELECT ProductModelID,
    AVG(ListPrice) AS [Average List Price]
FROM Production.Product
WHERE ListPrice > $1000
GROUP BY ProductModelID
ORDER BY ProductModelID;
GO

I. GROUP BY mit einem Ausdruck verwenden

Im folgenden Beispiel wird nach einem Ausdruck gruppiert. Sie können nach einem Ausdruck gruppieren, wenn dieser keine Aggregatfunktionen enthält.

USE AdventureWorks2022;
GO

SELECT AVG(OrderQty) AS [Average Quantity],
    NonDiscountSales = (OrderQty * UnitPrice)
FROM Sales.SalesOrderDetail
GROUP BY (OrderQty * UnitPrice)
ORDER BY (OrderQty * UnitPrice) DESC;
GO

J. GROUP BY mit ORDER BY verwenden

Im folgenden Beispiel wird zu jedem Produkttyp der Durchschnittspreis ermittelt, nach dem anschließend die Ergebnisse geordnet werden:

USE AdventureWorks2022;
GO

SELECT ProductID,
    AVG(UnitPrice) AS [Average Price]
FROM Sales.SalesOrderDetail
WHERE OrderQty > 10
GROUP BY ProductID
ORDER BY AVG(UnitPrice);
GO

K. Die HAVING-Klausel verwenden

Im ersten Beispiel wird eine HAVING-Klausel mit einer Aggregatfunktion gezeigt. Sie gruppiert die Zeilen in der SalesOrderDetail-Tabelle nach Produkt-ID und entfernt Produkte, deren durchschnittliche Bestellmenge mit 5 oder weniger angegeben ist. Im zweiten Beispiel wird eine HAVING-Klausel ohne Aggregatfunktionen gezeigt.

USE AdventureWorks2022;
GO

SELECT ProductID
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO

Diese Abfrage verwendet die LIKE-Klausel in der HAVING-Klausel.

USE AdventureWorks2022;
GO
SELECT SalesOrderID, CarrierTrackingNumber
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID, CarrierTrackingNumber
HAVING CarrierTrackingNumber LIKE '4BD%'
ORDER BY SalesOrderID ;
GO

L. HAVING und GROUP BY verwenden

Im folgenden Beispiel wird die Verwendung der Klauseln GROUP BY, HAVING, WHERE und ORDER BY in einer SELECT-Anweisung gezeigt. Sie erzeugt Gruppen und Summenwerte jedoch erst, nachdem alle Produkte entfernt wurden, deren Preise über 25 $ liegen und für die Bestellmengen unter 5 angegeben sind. Außerdem werden die Ergebnisse nach der ProductID-Spalte sortiert.

USE AdventureWorks2022;
GO

SELECT ProductID
FROM Sales.SalesOrderDetail
WHERE UnitPrice < 25.00
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO

M. HAVING mit SUM und AVG verwenden

Im folgenden Beispiel wird die SalesOrderDetail-Tabelle nach Produkt-ID gruppiert und nur die Produktgruppen eingeschlossen, für die Bestellungen mit einem Gesamtwert von mehr als $1000000.00 vorliegen und deren durchschnittliche Bestellmenge mit weniger als 3 angegeben ist.

USE AdventureWorks2022;
GO

SELECT ProductID,
    AVG(OrderQty) AS AverageQuantity,
    SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $1000000.00
    AND AVG(OrderQty) < 3;
GO

Mit der folgenden Abfrage können Sie alle Produkte abfragen, für die Verkäufe im Gesamtwert von über $2000000.00 verzeichnet wurden:

USE AdventureWorks2022;
GO

SELECT ProductID, Total = SUM(LineTotal)
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $2000000.00;
GO

Wenn Sie sicherstellen möchten, dass in die Berechnungen zu jedem Produkt mindestens 1.500 Artikel einfließen, entfernen Sie mit HAVING COUNT(*) > 1500 die Produkte, die Summen mit weniger als 1500 verkauften Artikeln zurückgeben. Die Abfrage sieht folgendermaßen aus:

USE AdventureWorks2022;
GO

SELECT ProductID, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(*) > 1500;
GO

N. Den INDEX-Optimiererhinweis verwenden

Im folgenden Beispiel werden zwei Möglichkeiten zum Verwenden des INDEX-Optimiererhinweises gezeigt. Das erste Beispiel zeigt, wie erzwungen werden kann, dass der Optimierer einen nicht gruppierten Index verwendet, um Zeilen aus einer Tabelle abzurufen. Im zweiten Beispiel wird ein Tabellenscan erzwungen, indem ein Index von 0 verwendet wird.

USE AdventureWorks2022;
GO

SELECT pp.FirstName,
    pp.LastName,
    e.NationalIDNumber
FROM HumanResources.Employee AS e WITH (INDEX (AK_Employee_NationalIDNumber))
INNER JOIN Person.Person AS pp
    ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO

-- Force a table scan by using INDEX = 0.
USE AdventureWorks2022;
GO

SELECT pp.LastName,
    pp.FirstName,
    e.JobTitle
FROM HumanResources.Employee AS e WITH (INDEX = 0)
INNER JOIN Person.Person AS pp
    ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO

M. Die OPTION- und GROUP-Hinweise verwenden

Im folgenden Beispiel wird gezeigt, wie die OPTION (GROUP)-Klausel in Verbindung mit einer GROUP BY-Klausel verwendet wird.

USE AdventureWorks2022;
GO

SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10);
GO

O. Den UNION-Abfragehinweis verwenden

Im folgenden Beispiel wird der MERGE UNION-Abfragehinweis verwendet.

USE AdventureWorks2022;
GO

SELECT BusinessEntityID,
    JobTitle,
    HireDate,
    VacationHours,
    SickLeaveHours
FROM HumanResources.Employee AS e1

UNION

SELECT BusinessEntityID,
    JobTitle,
    HireDate,
    VacationHours,
    SickLeaveHours
FROM HumanResources.Employee AS e2
OPTION (MERGE UNION);
GO

P. Eine UNION verwenden

Das Resultset im folgenden Beispiel enthält den Inhalt der Spalten ProductModelID und Name der Tabellen ProductModel und Gloves.

USE AdventureWorks2022;
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 AdventureWorks2022;
GO

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)

UNION

SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name;
GO

F: SELECT INTO mit UNION verwenden

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. Die Gloves-Tabelle wird in der ersten SELECT-Anweisung erstellt.

USE AdventureWorks2022;
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 AdventureWorks2022;
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 ProductModelID, Name
FROM dbo.ProductResults;

R. UNION in zwei SELECT-Anweisungen mit ORDER BY verwenden

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

USE AdventureWorks2022;
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 AdventureWorks2022;
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 AdventureWorks2022;
GO

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)

UNION

SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name;
GO

S. UNION mit drei SELECT-Anweisungen verwenden, 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 fünf 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, und fünf 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 fünf Zeilen zurück, weil die Option ALL nicht verwendet wird und Duplikate gelöscht werden. Diese fünf Zeilen werden mit den Ergebnissen der ersten SELECT-Anweisung mithilfe der UNION ALL-Schlüsselwörter kombiniert. In diesem Beispiel werden die Duplikate in den beiden aus fünf Zeilen bestehenden Resultsets nicht gelöscht. Das Endergebnis enthält 10 Zeilen.

USE AdventureWorks2022;
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
INNER 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
INNER 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
INNER 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