Freigeben über


TOP (Transact-SQL)

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) SQL-Analyseendpunkt in Microsoft Fabric Warehouse in Microsoft Fabric SQL-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 TOP in Verbindung mit der ORDER BY-Klausel verwendet wird, ist das Resultset auf die ersten N sortierten Zeilen beschränkt. Andernfalls gibt TOP die ersten N Zeilen in zufälliger Reihenfolge zurück. Verwenden Sie diese Klausel, um die Anzahl der von einer SELECT-Anweisung zurückgegebenen Zeilen anzugeben. Oder verwenden Sie TOP, um die Zeilen anzugeben, die von einer INSERT-, UPDATE-, MERGE- oder DELETE-Anweisung betroffen sind.

Transact-SQL-Syntaxkonventionen

Syntax

Die folgende Syntax gilt für SQL Server und Azure SQL-Datenbank:

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

Die folgende Syntax gilt für Azure Synapse Analytics und Analytics Platform System (PDW):

[   
    TOP ( expression )   
    [ WITH TIES ]  
]  

Argumente

expression
Der numerische Ausdruck, der die Anzahl der zurückzugebenden Zeilen angibt. expression wird implizit in einen float-Wert konvertiert, wenn PERCENT angegeben ist. 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. Durch WITH TIES werden möglicherweise mehr Zeilen zurückgegeben, als der Wert in expression angibt. Wenn beispielsweise expression auf den Wert „5“ festgelegt ist, aber zwei weitere Zeilen den Werten der ORDER BY-Spalten in Zeile 5 entsprechen, enthält das Resultset sieben Zeilen.

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

Empfehlungen

Verwenden Sie in einer SELECT-Anweisung immer eine ORDER BY-Klausel mit einer TOP-Klausel. Denn dies ist die einzige Möglichkeit, zuverlässig anzugeben, welche Zeilen von TOP betroffen sind.

Verwenden Sie OFFSET und FETCH in der ORDER BY-Klausel anstelle der TOP-Klausel, um eine Abfrageauslagerung zu implementieren. Eine Abfrageauslagerung (d. h. das Senden von Abschnitten oder "Seiten" von Daten an den Client) kann leichter mit OFFSET- und FETCH-Klauseln implementiert werden. Weitere Informationen finden Sie unter ORDER BY-Klausel (Transact-SQL).

Schränken Sie die Anzahl der zurückgegebenen Zeilen mithilfe von TOP (oder OFFSET und FETCH) anstelle von SET ROWCOUNT ein. Diese Methoden werden SET ROWCOUNT aus folgenden Gründen vorgezogen:

  • Im Rahmen einer SELECT-Anweisung kann der Wert von expression in der TOP- oder der FETCH-Klausel vom Abfrageoptimierer während der Abfrageoptimierung berücksichtigt werden. Da SET ROWCOUNT außerhalb einer Anweisung verwendet wird, die eine Abfrage ausführt, kann ihr Wert nicht in einem Abfrageplan berücksichtigt werden.

Kompatibilitätsunterstützung

Aus Gründen der Abwärtskompatibilität sind die Klammern in SELECT-Anweisungen optional, wenn es sich bei dem Ausdruck um eine ganzzahlige Konstante handelt. Es empfiehlt sich, in SELECT-Anweisungen immer Klammern für TOP zu verwenden. Damit erzielen Sie Konsistenz mit der erforderlichen Verwendung in INSERT-, UPDATE-, MERGE- und DELETE-Anweisungen.

Interoperabilität

Der TOP-Ausdruck wirkt sich nicht auf Anweisungen aus, die möglicherweise wegen eines Triggers ausgeführt werden. Die Tabellen inserted und deleted in den Triggern geben nur die Zeilen zurück, die tatsächlich von den INSERT-, UPDATE- MERGE- oder DELETE-Anweisungen betroffen sind. Beispiel: Ein INSERT TRIGGER, der aufgrund einer INSERT-Anweisung mit einer TOP-Klausel ausgelöst wird.

SQL Server ermöglicht das Aktualisieren von Zeilen über Sichten. Weil die TOP-Klausel in die Sichtdefinition einbezogen werden kann, werden bestimmte Zeilen aufgrund eines Updates möglicherweise nicht mehr in der Sicht angezeigt, wenn die Zeilen die Anforderungen des TOP-Ausdrucks nicht mehr erfüllen.

Bei Angabe in der MERGE-Anweisung 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 verringert zudem die Anzahl der verknüpften Zeilen auf den angegebenen Wert, und die INSERT-, UPDATE- oder DELETE-Aktionen werden ungeordnet auf die verbliebenen verknüpften Zeilen angewendet. Dies bedeutet, dass für die Verteilung der Zeilen auf die in den WHEN-Klauseln definierten Aktionen keine bestimmte Reihenfolge gilt. Wenn beispielsweise die Angabe von „TOP (10)“ 10 Zeilen betrifft, werden sieben davon aktualisiert und drei eingefügt. Möglicherweise werden auch fünf Zeilen aktualisiert, vier eingefügt und eine gelöscht usw. Da die MERGE-Anweisung einen vollständigen Tabellenscan der Quell- und der Zieltabelle ausführt, kann die E/A-Leistung beeinträchtigt werden, wenn Sie mit der TOP-Klausel eine große Tabelle durch Erstellen mehrerer Batches ändern. In diesem Szenario muss unbedingt sichergestellt werden, dass alle aufeinanderfolgenden Batches auf neue Zeilen ausgerichtet sind.

Geben Sie die TOP-Klausel in einer Abfrage mit einem UNION-, UNION ALL-, EXCEPT- oder INTERSECT-Operator mit Bedacht an. Es ist denkbar, dass eine Abfrage geschrieben wird, die unerwartete Ergebnisse zurückgibt, weil die Reihenfolge der logischen Verarbeitung für die TOP-Klausel und die ORDER BY-Klausel nicht immer intuitiv ist, wenn diese Operatoren in einem SELECT-Vorgang 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    

Nachfolgend ist das Resultset dargestellt.

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

Die unerwarteten Ergebnisse werden zurückgegeben, weil die logische Ausführung der TOP-Klausel vor der logischen Ausführung der ORDER BY-Klausel erfolgt, mit der die Ergebnisse des Operators (in diesem Fall UNION ALL) sortiert werden. 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    

Durch die Verwendung von TOP und ORDER BY in einem untergeordneten SELECT-Vorgang stellen Sie sicher, dass die Ergebnisse der ORDER BY-Klausel auf die TOP-Klausel angewendet werden und damit nicht das Ergebnis des UNION-Vorgangs sortiert wird.

Hier ist das Resultset.

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

Einschränkungen

Wenn Sie TOP mit INSERT, UPDATE, MERGE oder DELETE verwenden, werden die referenzierten Zeilen in keiner bestimmten Reihenfolge angeordnet. Und Sie können die ORDER BY-Klausel nicht direkt in diesen Anweisungen angeben. Wenn Sie die TOP-Klausel verwenden müssen, um Zeilen in einer sinnvollen Reihenfolge einzufügen, zu löschen oder zu bearbeiten, verwenden Sie TOP mit einer ORDER BY-Klausel in einer untergeordneten SELECT-Anweisung. Beachten Sie in diesem Zusammenhang den folgenden Abschnitt „Beispiele“ in diesem Artikel.

TOP kann nicht in UPDATE- und DELETE-Anweisungen für partitionierte Sichten verwendet werden.

TOP kann nicht mit OFFSET und FETCH im gleichen Abfrageausdruck (im gleichen Abfragebereich) kombiniert werden. Weitere Informationen finden Sie unter ORDER BY-Klausel (Transact-SQL).

Beispiele

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

Anhand von Beispielen in diesem Abschnitt wird die grundlegende Funktion der ORDER BY-Klausel mithilfe der mindestens erforderlichen Syntax veranschaulicht.

A. Verwenden von TOP mit einem konstanten Wert

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 nicht definierten Zeilen zurückgegeben, weil keine ORDER BY-Klausel verwendet wird. Im zweiten Beispiel wird eine ORDER BY-Klausel verwendet, um die ersten 10 Mitarbeiter zurückzugeben, die kürzlich eingestellt wurden.

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 die Anzahl der Mitarbeiter, die im Abfrageresultset zurückgegeben werden, mit PERCENT angegeben. 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    

Einschließen von gleichwertigen Werten

A. Einschließen von Zeilen mit identischen Werten wie vorangehende Zeilen mit WITH TIES

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    

Beschränken der von ENTF, INSERT oder UPDATE betroffenen Zeilen

A. Verwenden von TOP, um die Anzahl der zu löschenden Zeilen einzuschränken

Wenn Sie eine TOP (n)-Klausel mit DELETE verwenden, wird der Löschvorgang für eine nicht definierte Auswahl von n Zeilen ausgeführt. Das heißt, die DELETE-Anweisung wählt eine beliebige Anzahl (n) von Zeilen aus, die die in der WHERE-Klausel definierten Kriterien erfüllen. 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 die TOP-Klausel verwenden möchten, um Zeilen in einer sinnvollen Reihenfolge zu löschen, verwenden Sie TOP mit ORDER BY in einer untergeordneten SELECT-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. Wird in der untergeordneten SELECT-Anweisung eine Nichtschlüsselspalte verwendet, werden möglicherweise mehr als 10 Zeilen gelöscht, wenn die angegebene Spalte doppelte Werte enthält.

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

B. Einschränken der Anzahl eingefügter Zeilen mit TOP

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 fünf Zeilen aus, die von der SELECT-Anweisung zurückgegeben werden, die die in der WHERE-Klausel definierten Kriterien erfüllen. Mit der OUTPUT-Klausel werden die Zeilen angezeigt, die in die EmployeeSales-Tabelle eingefügt werden. Beachten Sie, dass die ORDER BY-Klausel in der SELECT-Anweisung nicht zum Ermitteln der ersten fünf Mitarbeiter verwendet wird.

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 die TOP-Klausel verwenden möchten, um Zeilen in einer sinnvollen Reihenfolge einzufügen, verwenden Sie TOP mit ORDER BY in einer untergeordneten SELECT-Anweisung. Dies wird im folgenden Beispiel veranschaulicht. Mit der OUTPUT-Klausel werden die Zeilen angezeigt, die in die EmployeeSales-Tabelle eingefügt werden. Beachten Sie, dass die ersten fünf Mitarbeiter jetzt basierend auf den Ergebnissen der ORDER BY-Klausel und nicht anhand nicht definierter Zeilen eingefügt werden.

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. Einschränken der Anzahl aktualisierter Zeilen mit TOP

Im folgenden Beispiel wird die TOP-Klausel zur Aktualisierung von Zeilen in einer Tabelle verwendet. Wenn Sie eine TOP (n)-Klausel mit UPDATE verwenden, wird der Updatevorgang für eine nicht definierte Anzahl von Zeilen ausgeführt. Das heißt, die UPDATE-Anweisung wählt eine beliebige Anzahl (n) von Zeilen aus, die die in der WHERE-Klausel definierten Kriterien erfüllen. 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 TOP verwendet werden muss, um Updates in einer sinnvollen Abfolge anzuwenden, muss in einer untergeordneten SELECT-Anweisung TOP gemeinsam mit ORDER BY verwendet werden. 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. Mit der ORDER BY-Klausel wird sichergestellt, dass es sich bei den 31 zurückgegebenen Zeilen um die ersten 31 Zeilen (basierend auf einer alphabetischen Sortierung der Spalte LastName) handelt.

Verwenden Sie TOP, ohne WITH TIES anzugeben.

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

Ergebnis: 31 Zeilen werden zurückgegeben.

Verwenden Sie TOP mit Angabe von WITH TIES.

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

Ergebnis: 33 Zeilen werden zurückgegeben, da drei Mitarbeiter namens „Brown“ in der 31. Zeile vorhanden sind.

Weitere Informationen

SELECT (Transact-SQL)
INSERT (Transact-SQL)
UPDATE (Transact-SQL)
DELETE (Transact-SQL)
ORDER BY-Klausel (Transact-SQL)
SET ROWCOUNT (Transact-SQL)
MERGE (Transact-SQL)