Freigeben über


TOP (Transact-SQL)

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)SQL-Analyseendpunkt in Microsoft FabricWarehouse in Microsoft FabricSQL-Datenbank in Microsoft Fabric

Begrenzt die zurückgegebenen Zeilen in einem Abfrageresultset auf die in SQL Server angegebene Anzahl bzw. den darin angegebenen diesbezüglichen Prozentwert. Wenn Sie TOP mit der ORDER BY-Klausel verwenden, ist das Resultset auf die erste n Anzahl sortierter Zeilen beschränkt. Andernfalls gibt TOP die erste n Anzahl von Zeilen in einer nicht definierten Reihenfolge zurück. Verwenden Sie diese Klausel, um die Anzahl der zeilen anzugeben, die von einer SELECT-Anweisung zurückgegeben werden. Oder verwenden Sie TOP, um die zeilen anzugeben, die von einer INSERT, UPDATE, MERGEoder DELETE Anweisung betroffen sind.

Transact-SQL-Syntaxkonventionen

Syntax

Syntax für SQL Server und Azure SQL-Datenbank:

[
    TOP (expression) [ PERCENT ]
    [ WITH TIES ]
]

Syntax für Azure Synapse Analytics and Analytics Platform System (PDW):

[
    TOP ( expression )
    [ WITH TIES ]
]

Argumente

expression

Der numerische Ausdruck, der die Anzahl der zurückzugebenden Zeilen angibt. Ausdruck wird implizit in einen wert float konvertiert, wenn Sie PERCENTangeben. Andernfalls wird expression in bigint konvertiert.

PERCENT

Gibt an, dass die Abfrage nur die ersten expression Prozent der Zeilen aus dem Resultset zurückgibt. Bruchwerte werden auf den nächsten ganzzahligen Wert aufgerundet.

WITH TIES

Gibt mindestens zwei Zeilen zurück, die zeitgleich den letzten Platz im beschränkten Resultset belegen. Sie müssen dieses Argument mit der ORDER BY-Klausel verwenden. WITH TIES können dazu führen, dass mehr Zeilen zurückgegeben werden, als der in Ausdruckangegebene Wert. Wenn beispielsweise Ausdruck auf 5 festgelegt ist, aber zwei weitere Zeilen mit den Werten der ORDER BY Spalten in Zeile 5 übereinstimmen, enthält das Resultset sieben Zeilen.

Sie können die TOP Klausel nur in SELECT-Anweisungen mit dem argument WITH TIES angeben, und nur, wenn Sie auch die ORDER BY Klausel angeben. Die zurückgegebene Reihenfolge beim Binden von Datensätzen ist willkürlich. ORDER BY wirkt sich nicht auf diese Regel aus.

Bewährte Methoden

Verwenden Sie in einer SELECT-Anweisung immer eine ORDER BY-Klausel mit der TOP-Klausel. Dies ist die einzige Möglichkeit, vorhersagbar anzugeben, welche Zeilen von TOPbetroffen sind.

Verwenden Sie OFFSET und FETCH in der ORDER BY-Klausel anstelle der TOP-Klausel, um eine Abfrage paging-Lösung zu implementieren. Eine Auslagerungslösung (d. h. das Senden von Blöcken oder Seiten von Daten an den Client) ist einfacher, mithilfe von OFFSET- und FETCH-Klauseln zu implementieren. Weitere Informationen finden Sie unter SELECT - ORDER BY-Klausel.

Verwenden Sie TOP (oder OFFSET und FETCH) anstelle von SET ROWCOUNT, um die Anzahl der zurückgegebenen Zeilen einzuschränken. Diese Methoden werden aus folgenden Gründen gegenüber der Verwendung von SET ROWCOUNT bevorzugt:

  • Als Teil einer SELECT-Anweisung kann der Abfrageoptimierer den Wert Ausdrucks in den TOP oder FETCH Klauseln während der Abfrageoptimierung berücksichtigen. Da Sie SET ROWCOUNT außerhalb einer Anweisung verwenden, die eine Abfrage ausführt, kann der Wert in einem Abfrageplan nicht berücksichtigt werden.

Kompatibilitätsunterstützung

Aus Gründen der Abwärtskompatibilität sind die Klammern in SELECT Anweisungen optional, wenn der Ausdruck eine ganze Zahl ist. Es wird empfohlen, in SELECT Anweisungen immer Klammern für TOP zu verwenden. Dies bietet Konsistenz mit der erforderlichen Verwendung in INSERT, UPDATE, MERGEund DELETE Anweisungen.

Interoperabilität

Der ausdruck TOP wirkt sich nicht auf Anweisungen aus, die aufgrund eines Triggers ausgeführt werden können. Die Tabellen inserted und deleted in den Triggern geben nur die Zeilen zurück, die wirklich von den Anweisungen INSERT, UPDATE, MERGEoder DELETE betroffen sind. Wenn beispielsweise ein INSERT TRIGGER als Ergebnis einer INSERT-Anweisung ausgelöst wird, die eine TOP-Klausel verwendet hat.

SQL Server ermöglicht das Aktualisieren von Zeilen über Sichten. Da Sie die TOP-Klausel in die Ansichtsdefinition einschließen können, können bestimmte Zeilen aus der Ansicht ausgeblendet werden, wenn die Zeilen aufgrund einer Aktualisierung nicht mehr den Anforderungen des TOP Ausdrucks entsprechen.

Wenn in der MERGE-Anweisung angegeben, wird die TOP-Klausel angewendet, nachdem die gesamte Quelltabelle und die gesamte Zieltabelle verknüpft wurden. Und die verknüpften Zeilen, die nicht für eine INSERT-, UPDATE- oder DELETE-Aktion infrage kommen, werden entfernt. Die TOP Klausel reduziert die Anzahl verknüpfter Zeilen weiter auf den angegebenen Wert, und die Einfüge-, Aktualisierungs- oder Löschaktionen gelten für die verbleibenden verknüpften Zeilen auf ungeordnete Weise. Das heißt, es gibt keine Reihenfolge, in der die Zeilen zwischen den in den WHEN Klauseln definierten Aktionen verteilt werden. Wenn sich beispielsweise die Angabe von TOP (10) auf 10 Zeilen auswirkt, können sieben dieser Zeilen aktualisiert und drei eingefügt werden. Oder eine kann gelöscht, fünf aktualisiert und vier eingefügt werden usw. Da die MERGE-Anweisung eine vollständige Tabellenüberprüfung der Quell- und Zieltabellen durchführt, kann die E/A-Leistung beeinträchtigt werden, wenn Sie die TOP-Klausel zum Ändern einer großen Tabelle verwenden, indem Sie mehrere Batches erstellen. In diesem Szenario muss unbedingt sichergestellt werden, dass alle aufeinanderfolgenden Batches auf neue Zeilen ausgerichtet sind.

Gehen Sie vorsichtig vor, wenn Sie die TOP-Klausel in einer Abfrage angeben, die einen operator mit UNION, UNION ALL, EXCEPToder INTERSECT enthält. Es ist möglich, eine Abfrage zu schreiben, die unerwartete Ergebnisse zurückgibt, da die Reihenfolge, in der die TOP und ORDER BY Klauseln logisch verarbeitet werden, nicht immer intuitiv ist, wenn diese Operatoren in einem Auswahlvorgang verwendet werden. Beispiel: Für die folgende Tabelle und die darin enthaltenen Daten sollen das günstigste rote Auto sowie das günstigste blaue Auto zurückgeben werden. Dies sind der rote PKW und der blaue LKW.

CREATE TABLE dbo.Cars
(
    Model VARCHAR (15),
    Price MONEY,
    Color VARCHAR (10)
);

INSERT dbo.Cars
VALUES ('sedan', 10000, 'red'),
    ('convertible', 15000, 'blue'),
    ('coupe', 20000, 'red'),
    ('van', 8000, 'blue');

Um diese Ergebnisse zu erreichen, können Sie die folgende Abfrage schreiben:

SELECT TOP (1) Model, Color, Price
FROM dbo.Cars
WHERE Color = 'red'
UNION ALL
SELECT TOP (1) Model, Color, Price
FROM dbo.Cars
WHERE Color = 'blue'
ORDER BY Price ASC;
GO

Hier sehen Sie das Resultset.

 Model         Color      Price
 ------------- ---------- -------
 sedan         red        10000.00
 convertible   blue       15000.00

Die unerwarteten Ergebnisse werden zurückgegeben, da die TOP-Klausel logisch vor der ORDER BY-Klausel ausgeführt wird, wodurch die Ergebnisse des Operators sortiert werden (UNION ALL in diesem Fall). So werden von der vorherigen Abfrage ein beliebiges rotes und ein beliebiges blaues Auto zurückgegeben, und dann wird das Ergebnis dieser Union nach dem Preis sortiert. Im folgenden Beispiel wird veranschaulicht, wie eine Abfrage geschrieben wird, um das gewünschte Ergebnis zu erzielen.

SELECT Model, Color, Price
FROM (SELECT TOP (1) Model, Color, Price
      FROM dbo.Cars
      WHERE Color = 'red'
      ORDER BY Price ASC) AS a
UNION ALL
SELECT Model, Color, Price
FROM (SELECT TOP (1) Model, Color, Price
      FROM dbo.Cars
      WHERE Color = 'blue'
      ORDER BY Price ASC) AS b;
GO

Mithilfe von TOP und ORDER BY in einem Unterauswahlvorgang stellen Sie sicher, dass die Ergebnisse der ORDER BY-Klausel auf die TOP-Klausel angewendet werden und nicht auf das Ergebnis des UNION-Vorgangs.

Hier sehen Sie das Resultset.

 Model         Color      Price
 ------------- ---------- -------
 sedan         red        10000.00
 van           blue        8000.00

Begrenzungen

Wenn Sie TOP mit INSERT, UPDATE, MERGEoder DELETEverwenden, werden die referenzierten Zeilen in keiner Reihenfolge angeordnet. Außerdem können Sie die ORDER BY Klausel in diesen Anweisungen nicht direkt angeben. Wenn Sie TOP zum Einfügen, Löschen oder Ändern von Zeilen in einer sinnvollen chronologischen Reihenfolge verwenden müssen, verwenden Sie TOP mit einer ORDER BY Klausel, die in einer Subselect-Anweisung angegeben ist. Weitere Informationen finden Sie im Abschnitt Beispiele in diesem Artikel.

Sie können TOP nicht in UPDATE oder DELETE Anweisungen für partitionierte Ansichten verwenden.

Sie können TOP nicht mit OFFSET und FETCH im gleichen Abfrageausdruck (im gleichen Abfragebereich) kombinieren. Weitere Informationen finden Sie unter SELECT - ORDER BY-Klausel.

Beispiele

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

Category Funktionssyntaxelemente
Grundlegende Syntax TOP * PERCENT
Einschließen von gleichwertigen Werten WITH TIES
Beschränken der von DELETE, INSERT oder UPDATE betroffenen Zeilen DELETE, INSERT, UPDATE

Grundlegende Syntax

Beispiele in diesem Abschnitt veranschaulichen die grundlegenden Funktionen der ORDER BY Klausel mit der minimal erforderlichen Syntax.

A. Verwenden von TOP mit einem Konstantenwert

In den folgenden Beispielen wird die Anzahl der Mitarbeiter, die in einem Abfrageresultset zurückgegeben werden, mit einem konstanten Wert angegeben. Im ersten Beispiel werden die ersten 10 undefinierten Zeilen zurückgegeben, da keine ORDER BY Klausel verwendet wird. Im zweiten Beispiel wird eine ORDER BY Klausel verwendet, um die top 10 zuletzt eingestellten Mitarbeiter zurückzugeben.

USE AdventureWorks2022;
GO

-- Select the first 10 random employees.
SELECT TOP (10) JobTitle, HireDate
FROM HumanResources.Employee;
GO

-- Select the first 10 employees hired most recently.
SELECT TOP (10) JobTitle, HireDate
FROM HumanResources.Employee
ORDER BY HireDate DESC;
GO

B. Verwenden von TOP mit einer Variablen

Im folgenden Beispiel wird die Anzahl der Mitarbeiter, die im Abfrageresultset zurückgegeben werden, mit einer Variablen angegeben.

USE AdventureWorks2022;
GO

DECLARE @p AS INT = 10;

SELECT TOP (@p) JobTitle, HireDate, VacationHours
FROM HumanResources.Employee
ORDER BY VacationHours DESC;
GO

C. Angeben eines Prozentsatzes

Im folgenden Beispiel wird PERCENT verwendet, um die Anzahl der Mitarbeiter anzugeben, die im Abfrageergebnissatz zurückgegeben werden. Die Tabelle HumanResources.Employee enthält 290 Mitarbeiter. Da fünf Prozent von 290 ein Dezimalstellenwert ist, wird der Wert auf die nächste ganze Zahl aufgerundet.

USE AdventureWorks2022;
GO

SELECT TOP (5) PERCENT JobTitle, HireDate
FROM HumanResources.Employee
ORDER BY HireDate DESC;
GO

Binden von Werten einschließen

A. Verwenden von WITH TIES zum Einschließen von Zeilen, die den Werten in der letzten Zeile entsprechen

Im folgenden Beispiel werden die obersten 10 Prozent aller Mitarbeiter mit dem höchsten Gehalt abgerufen und in absteigender Reihenfolge nach der Höhe des Gehalts zurückgegeben. Durch Angeben von WITH TIES wird sichergestellt, dass alle Mitarbeiter mit einem Gehalt, das dem niedrigsten zurückgegebenen Gehalt (der letzten Zeile) entspricht, ebenfalls im Resultset enthalten sind, auch wenn dadurch 10 Prozent der Mitarbeiter überschritten werden.

USE AdventureWorks2022;
GO

SELECT TOP (10) PERCENT WITH TIES pp.FirstName,
                                  pp.LastName,
                                  e.JobTitle,
                                  e.Gender,
                                  r.Rate
FROM Person.Person AS pp
     INNER JOIN HumanResources.Employee AS e
         ON pp.BusinessEntityID = e.BusinessEntityID
     INNER JOIN HumanResources.EmployeePayHistory AS r
         ON r.BusinessEntityID = e.BusinessEntityID
ORDER BY Rate DESC;
GO

Einschränken der zeilen, die durch DELETE, INSERT oder UPDATE betroffen sind

A. Verwenden von TOP zum Einschränken der Anzahl gelöschter Zeilen

Wenn Sie eine TOP (<n>)-Klausel mit DELETEverwenden, wird der Löschvorgang für eine nicht definierte Auswahl von n Anzahl von Zeilen ausgeführt. Das heißt, die DELETE-Anweisung wählt eine beliebige (n) Anzahl von Zeilen aus, die den in der WHERE-Klausel definierten Kriterien entsprechen. Im folgenden Beispiel werden 20 Zeilen mit einem Fälligkeitsdatum vor dem 1. Juli 2002 aus der Tabelle PurchaseOrderDetail gelöscht.

USE AdventureWorks2022;
GO

DELETE TOP (20)
FROM Purchasing.PurchaseOrderDetail
WHERE DueDate < '20020701';
GO

Wenn Sie TOP verwenden möchten, um Zeilen in einer sinnvollen chronologischen Reihenfolge zu löschen, verwenden Sie TOP mit ORDER BY in einer Subselect-Anweisung. Die folgende Abfrage löscht die zehn Zeilen der PurchaseOrderDetail -Tabelle mit den frühesten Fälligkeitsdaten. Die in der untergeordneten SELECT-Anweisung angegebene Spalte (PurchaseOrderID) ist der Primärschlüssel der Tabelle, um sicherzustellen, dass nur 10 Zeilen gelöscht werden. Die Verwendung einer nicht schlüsselfreien Spalte in der Subselect-Anweisung kann dazu führen, dass mehr als 10 Zeilen gelöscht werden, wenn die angegebene Spalte doppelte Werte enthält.

USE AdventureWorks2022;
GO

DELETE Purchasing.PurchaseOrderDetail
WHERE PurchaseOrderDetailID IN (
    SELECT TOP 10 PurchaseOrderDetailID
    FROM Purchasing.PurchaseOrderDetail
    ORDER BY DueDate ASC
);
GO

B. Verwenden von TOP zum Einschränken der Anzahl eingefügter Zeilen

Im folgenden Beispiel wird die Tabelle EmployeeSales erstellt, und der Name und die Verkaufszahlen des laufenden Jahres für die ersten fünf Mitarbeiter aus der Tabelle HumanResources.Employee werden eingefügt. Die INSERT-Anweisung wählt alle fünf Zeilen aus, die von der SELECT-Anweisung zurückgegeben werden, die den in der WHERE-Klausel definierten Kriterien entsprechen. Die OUTPUT-Klausel zeigt die Zeilen an, die in die EmployeeSales Tabelle eingefügt werden. Die ORDER BY-Klausel in der SELECT-Anweisung wird nicht verwendet, um die fünf obersten Mitarbeiter zu bestimmen.

USE AdventureWorks2022;
GO

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

CREATE TABLE dbo.EmployeeSales
(
    EmployeeID NVARCHAR (11) NOT NULL,
    LastName NVARCHAR (20) NOT NULL,
    FirstName NVARCHAR (20) NOT NULL,
    YearlySales MONEY NOT NULL
);
GO

INSERT TOP (5) INTO dbo.EmployeeSales
OUTPUT
    inserted.EmployeeID,
    inserted.FirstName,
    inserted.LastName,
    inserted.YearlySales
SELECT sp.BusinessEntityID,
       c.LastName,
       c.FirstName,
       sp.SalesYTD
FROM Sales.SalesPerson AS sp
     INNER JOIN Person.Person AS c
         ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.SalesYTD > 250000.00
ORDER BY sp.SalesYTD DESC;
GO

Wenn Sie TOP verwenden möchten, um Zeilen in eine sinnvolle chronologische Reihenfolge einzufügen, verwenden Sie TOP mit ORDER BY in einer Subselect-Anweisung. Das folgende Beispiel zeigt, wie dies funktioniert. Die OUTPUT-Klausel zeigt die Zeilen an, die in die EmployeeSales Tabelle eingefügt werden. Die fünf obersten Mitarbeiter werden nun basierend auf den Ergebnissen der ORDER BY Klausel anstelle von nicht definierten Zeilen eingefügt.

INSERT INTO dbo.EmployeeSales
OUTPUT
    inserted.EmployeeID,
    inserted.FirstName,
    inserted.LastName,
    inserted.YearlySales
SELECT TOP (5) sp.BusinessEntityID,
               c.LastName,
               c.FirstName,
               sp.SalesYTD
FROM Sales.SalesPerson AS sp
     INNER JOIN Person.Person AS c
         ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.SalesYTD > 250000.00
ORDER BY sp.SalesYTD DESC;
GO

C. Verwenden von TOP, um die Anzahl der aktualisierten Zeilen zu begrenzen

Im folgenden Beispiel wird die TOP-Klausel verwendet, um Zeilen in einer Tabelle zu aktualisieren. Wenn Sie eine TOP (<n>) Klausel mit UPDATEverwenden, wird der Aktualisierungsvorgang für eine nicht definierte Anzahl von Zeilen ausgeführt. Das heißt, die UPDATE-Anweisung wählt eine beliebige (n) Anzahl von Zeilen aus, die den in der WHERE-Klausel definierten Kriterien entsprechen. Im folgenden Beispiel werden 10 Kunden von einem Vertriebsmitarbeiter zu einem anderen zugewiesen.

USE AdventureWorks2022;

UPDATE TOP (10)
Sales.Store
SET SalesPersonID = 276
WHERE SalesPersonID = 275;
GO

Wenn Sie TOP verwenden müssen, um Aktualisierungen in einer sinnvollen Chronologie anzuwenden, müssen Sie TOP zusammen mit ORDER BY in einer Subselect-Anweisung verwenden. Mit dem nachfolgenden Beispiel werden die Urlaubsstunden der 10 Mitarbeiter mit dem frühesten Einstellungsdatum aktualisiert.

UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 BusinessEntityID
      FROM HumanResources.Employee
      ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;
GO

Beispiele: Azure Synapse Analytics und Analytics-Plattformsystem (PDW)

Im folgenden Beispiel werden die obersten 31 Zeilen zurückgegeben, die den Abfragekriterien entsprechen. Die ORDER BY-Klausel stellt sicher, dass die zurückgegebenen 31 Zeilen die ersten 31 Zeilen sind, die auf einer alphabetischen Reihenfolge der LastName Spalte basieren.

Verwenden von TOP ohne Angabe von Bindungen.

SELECT TOP (31) FirstName, LastName
FROM DimEmployee
ORDER BY LastName;

Ergebnis: 31 Zeilen werden zurückgegeben.

Verwenden Sie TOP, und geben Sie WITH TIESan.

SELECT TOP (31) WITH TIES FirstName, LastName
FROM DimEmployee
ORDER BY LastName;

Ergebnis: 33 Zeilen werden zurückgegeben, da drei Mitarbeiter Brown Bindung für die 31. Zeile benannt haben.