Delen via


TOP (Transact-SQL)

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)SQL Analytics-eindpunt in Microsoft FabricWarehouse in Microsoft FabricSQL-database in Microsoft Fabric

Hiermee beperkt u de rijen die worden geretourneerd in een queryresultatenset tot een opgegeven aantal rijen of percentage rijen in SQL Server. Wanneer u TOP gebruikt met de ORDER BY component, is de resultatenset beperkt tot de eerste n aantal geordende rijen. Anders retourneert TOP de eerste n aantal rijen in een niet-gedefinieerde volgorde. Gebruik deze component om het aantal rijen op te geven dat wordt geretourneerd door een SELECT instructie. Of gebruik TOP om de rijen op te geven die worden beïnvloed door een INSERT, UPDATE, MERGEof DELETE instructie.

Transact-SQL syntaxisconventies

Syntaxis

Syntaxis voor SQL Server en Azure SQL Database:

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

Syntaxis voor Azure Synapse Analytics en Analytics Platform System (PDW):

[
    TOP ( expression )
    [ WITH TIES ]
]

Argumenten

expressie

De numerieke expressie waarmee het aantal rijen wordt opgegeven dat moet worden geretourneerd. expressie impliciet wordt geconverteerd naar een float- waarde als u PERCENTopgeeft. Anders wordt expressie geconverteerd naar bigint.

PROCENT

Geeft aan dat de query alleen de eerste expressie retourneert percentage rijen uit de resultatenset. Breukwaarden worden naar boven afgerond op de volgende gehele waarde.

MET TIES

Retourneert twee of meer rijen die gelijk zijn aan de laatste plaats in de beperkte resultatenset. U moet dit argument gebruiken met de ORDER BY component. WITH TIES kan ertoe leiden dat meer rijen worden geretourneerd dan de waarde die is opgegeven in expressie. Als expressie bijvoorbeeld is ingesteld op 5 maar twee rijen overeenkomen met de waarden van de ORDER BY kolommen in rij 5, bevat de resultatenset zeven rijen.

U kunt de TOP component alleen opgeven met het argument WITH TIES in SELECT instructies en alleen als u ook de ORDER BY component opgeeft. De geretourneerde volgorde van het koppelen van records is willekeurig. ORDER BY heeft geen invloed op deze regel.

Aanbevolen procedures

Gebruik in een SELECT-instructie altijd een ORDER BY-component met de TOP-component. Dit is de enige manier om voorspelbaar aan te geven welke rijen worden beïnvloed door TOP.

Gebruik OFFSET en FETCH in de ORDER BY-component in plaats van de TOP component om een oplossing voor het pagiëren van query's te implementeren. Een pagingoplossing (d.i.v. het verzenden van segmenten of pagina's van gegevens naar de client) is eenvoudiger te implementeren met behulp van OFFSET- en FETCH-componenten. Zie SELECT - ORDER BY-componentvoor meer informatie.

Gebruik TOP (of OFFSET en FETCH) in plaats van SET ROWCOUNT om het aantal geretourneerde rijen te beperken. Deze methoden hebben de voorkeur boven het gebruik van SET ROWCOUNT om de volgende redenen:

  • Als onderdeel van een SELECT-instructie kan de queryoptimalisatie de waarde van expressie in de TOP- of FETCH-componenten overwegen tijdens het optimaliseren van query's. Omdat u SET ROWCOUNT buiten een instructie gebruikt waarmee een query wordt uitgevoerd, kan de waarde ervan niet worden overwogen in een queryplan.

Compatibiliteitsondersteuning

Voor compatibiliteit met eerdere versies zijn de haakjes optioneel in SELECT instructies als de expressie een geheel getalconstante is. U wordt aangeraden altijd haakjes te gebruiken voor TOP in SELECT instructies. Dit biedt consistentie met het vereiste gebruik in INSERT, UPDATE, MERGEen DELETE instructies.

Interoperabiliteit

De TOP-expressie heeft geen invloed op instructies die kunnen worden uitgevoerd vanwege een trigger. De tabellen inserted en deleted in de triggers retourneren alleen de rijen die echt worden beïnvloed door de INSERT, UPDATE, MERGEof DELETE instructies. Als een INSERT TRIGGER bijvoorbeeld wordt geactiveerd als gevolg van een INSERT-instructie die een TOP component heeft gebruikt.

Met SQL Server kunt u rijen bijwerken via weergaven. Omdat u de TOP component in de weergavedefinitie kunt opnemen, kunnen bepaalde rijen uit de weergave verdwijnen als de rijen niet meer voldoen aan de vereisten van de TOP-expressie vanwege een update.

Wanneer de TOP-component is opgegeven in de MERGE-instructie, wordt toegepast nadat de hele brontabel en de hele doeltabel zijn gekoppeld. En de gekoppelde rijen die niet in aanmerking komen voor een actie invoegen, bijwerken of verwijderen, worden verwijderd. De TOP-component vermindert het aantal gekoppelde rijen verder op de opgegeven waarde en de invoeg-, bijwerk- of verwijderacties zijn van toepassing op de resterende gekoppelde rijen op een niet-geordende manier. Dat wil gezegd, er is geen volgorde waarin de rijen worden verdeeld over de acties die zijn gedefinieerd in de WHEN-componenten. Als het opgeven van TOP (10) bijvoorbeeld van invloed is op 10 rijen, kunnen zeven van deze rijen worden bijgewerkt en drie ingevoegd. Of één kan worden verwijderd, vijf bijgewerkt en vier ingevoegd, enzovoort. Omdat de MERGE-instructie een volledige tabelscan uitvoert van zowel de bron- als doeltabellen, kunnen de I/O-prestaties worden beïnvloed wanneer u de TOP-component gebruikt om een grote tabel te wijzigen door meerdere batches te maken. In dit scenario is het belangrijk om ervoor te zorgen dat alle opeenvolgende batches nieuwe rijen targeten.

Wees voorzichtig wanneer u de TOP component opgeeft in een query die een operator voor UNION, UNION ALL, EXCEPTof INTERSECT bevat. Het is mogelijk om een query te schrijven die onverwachte resultaten retourneert, omdat de volgorde waarin de TOP- en ORDER BY-componenten logisch worden verwerkt, niet altijd intuïtief is wanneer deze operators worden gebruikt in een selectiebewerking. Als u bijvoorbeeld de volgende tabel en gegevens opgeeft, moet u ervan uitgaan dat u de minst dure rode auto en de minst dure blauwe auto wilt retourneren. Dat wil gezegd, de rode sedan en de blauwe bus.

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');

Als u deze resultaten wilt bereiken, kunt u de volgende query schrijven.

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

Dit is de resultatenset.

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

De onverwachte resultaten worden geretourneerd omdat de TOP-component logisch wordt uitgevoerd vóór de ORDER BY-component, waarmee de resultaten van de operator worden gesorteerd (UNION ALL in dit geval). De vorige query retourneert dus een rode auto en een blauwe auto en bestelt vervolgens het resultaat van die samenvoeging door de prijs. In het volgende voorbeeld ziet u de juiste methode voor het schrijven van deze query om het gewenste resultaat te bereiken.

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

Met behulp van TOP en ORDER BY in een subselectiebewerking zorgt u ervoor dat de resultaten van de ORDER BY component worden toegepast op de TOP component en niet op het resultaat van de UNION bewerking sorteren.

Dit is de resultatenset.

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

Beperkingen

Wanneer u TOP gebruikt met INSERT, UPDATE, MERGEof DELETE, worden de rijen waarnaar wordt verwezen, in geen enkele volgorde gerangschikt. En u kunt de ORDER BY component niet rechtstreeks opgeven in deze instructies. Als u TOP wilt gebruiken om rijen in een zinvolle chronologische volgorde in te voegen, te verwijderen of te wijzigen, gebruikt u TOP met een ORDER BY component die is opgegeven in een subselectie-instructie. Zie de sectie Voorbeelden in dit artikel.

U kunt TOP niet gebruiken in UPDATE- of DELETE instructies voor gepartitioneerde weergaven.

U kunt TOP niet combineren met OFFSET en FETCH in dezelfde query-expressie (in hetzelfde querybereik). Zie SELECT - ORDER BY-componentvoor meer informatie.

Voorbeelden

De Transact-SQL codevoorbeelden in dit artikel gebruiken de AdventureWorks2022 of AdventureWorksDW2022 voorbeelddatabase, die u kunt downloaden van de Microsoft SQL Server-voorbeelden en communityprojecten startpagina.

Categorie Aanbevolen syntaxiselementen
basissyntaxis TOP * PERCENT
inclusief tiewaarden WITH TIES
de rijen die worden beïnvloed door DELETE, INSERT of UPDATE beperken DELETE, INSERT, UPDATE

Basissyntaxis

Voorbeelden in deze sectie laten de basisfunctionaliteit van de ORDER BY-component zien met behulp van de minimaal vereiste syntaxis.

Een. TOP gebruiken met een constante waarde

In de volgende voorbeelden wordt een constante waarde gebruikt om het aantal werknemers op te geven dat wordt geretourneerd in de queryresultatenset. In het eerste voorbeeld worden de eerste 10 niet-gedefinieerde rijen geretourneerd omdat er geen ORDER BY component wordt gebruikt. In het tweede voorbeeld wordt een ORDER BY component gebruikt om de tien laatst ingehuurde werknemers te retourneren.

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. TOP gebruiken met een variabele

In het volgende voorbeeld wordt een variabele gebruikt om het aantal werknemers op te geven dat wordt geretourneerd in de resultatenset van de query.

USE AdventureWorks2022;
GO

DECLARE @p AS INT = 10;

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

C. Een percentage opgeven

In het volgende voorbeeld wordt PERCENT gebruikt om het aantal werknemers op te geven dat wordt geretourneerd in de resultatenset van de query. De HumanResources.Employee tabel bevat 290 werknemers. Omdat vijf procent van 290 een breukwaarde is, wordt de waarde naar boven afgerond op het volgende gehele getal.

USE AdventureWorks2022;
GO

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

Gelijkwaarden opnemen

Een. GEBRUIK WITH TIES om rijen op te nemen die overeenkomen met de waarden in de laatste rij

In het volgende voorbeeld wordt het hoogste 10 percentage van alle werknemers met het hoogste salaris weergegeven en worden ze in aflopende volgorde geretourneerd op basis van hun salaris. Het opgeven van WITH TIES zorgt ervoor dat werknemers met salarissen gelijk zijn aan het laagste salaris dat wordt geretourneerd (de laatste rij) ook worden opgenomen in de resultatenset, zelfs als deze groter is dan 10 percentage werknemers.

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

De rijen beperken die worden beïnvloed door DELETE, INSERT of UPDATE

Een. Gebruik TOP om het aantal verwijderde rijen te beperken

Wanneer u een TOP (<n>)-component met DELETEgebruikt, wordt de verwijderbewerking uitgevoerd voor een niet-gedefinieerde selectie van n aantal rijen. Dat wil zeggen dat de DELETE instructie een willekeurig aantal rijen (n) kiest die voldoen aan de criteria die zijn gedefinieerd in de WHERE-component. In het volgende voorbeeld worden 20 rijen verwijderd uit de PurchaseOrderDetail tabel met einddatums die ouder zijn dan 1 juli 2002.

USE AdventureWorks2022;
GO

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

Als u TOP wilt gebruiken om rijen in een zinvolle chronologische volgorde te verwijderen, gebruikt u TOP met ORDER BY in een subselectie-instructie. Met de volgende query worden de 10 rijen van de PurchaseOrderDetail tabel verwijderd met de vroegste einddatums. Om ervoor te zorgen dat slechts 10 rijen worden verwijderd, is de kolom die is opgegeven in de subselectie-instructie (PurchaseOrderID) de primaire sleutel van de tabel. Als u een niet-sleutelkolom in de instructie subselectie gebruikt, kan dit leiden tot het verwijderen van meer dan 10 rijen als de opgegeven kolom dubbele waarden bevat.

USE AdventureWorks2022;
GO

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

B. Gebruik TOP om het aantal ingevoegde rijen te beperken

In het volgende voorbeeld wordt de tabel EmployeeSales gemaakt en worden de naam en de verkoopgegevens van het jaar tot heden ingevoegd voor de bovenste vijf werknemers uit de tabel HumanResources.Employee. De instructie INSERT kiest vijf rijen die worden geretourneerd door de SELECT-instructie die voldoet aan de criteria die zijn gedefinieerd in de WHERE-component. De OUTPUT-component geeft de rijen weer die in de EmployeeSales tabel zijn ingevoegd. De ORDER BY component in de SELECT-instructie wordt niet gebruikt om de vijf belangrijkste werknemers te bepalen.

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

Als u TOP wilt gebruiken om rijen in een zinvolle chronologische volgorde in te voegen, gebruikt u TOP met ORDER BY in een subselectie-instructie. In het volgende voorbeeld ziet u hoe u dit doet. De OUTPUT-component geeft de rijen weer die in de EmployeeSales tabel zijn ingevoegd. De vijf belangrijkste werknemers worden nu ingevoegd op basis van de resultaten van de ORDER BY component in plaats van niet-gedefinieerde rijen.

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. Gebruik TOP om het aantal bijgewerkte rijen te beperken

In het volgende voorbeeld wordt de TOP-component gebruikt om rijen in een tabel bij te werken. Wanneer u een TOP (<n>) component met UPDATEgebruikt, wordt de updatebewerking uitgevoerd op een niet-gedefinieerd aantal rijen. Dat wil zeggen dat de UPDATE instructie een willekeurig aantal rijen (n) kiest die voldoen aan de criteria die zijn gedefinieerd in de WHERE-component. In het volgende voorbeeld worden 10 klanten van de ene verkoper aan de andere toegewezen.

USE AdventureWorks2022;

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

Als u TOP moet gebruiken om updates toe te passen in een zinvolle chronologische volgorde, moet u TOP samen met ORDER BY gebruiken in een subselectie-instructie. In het volgende voorbeeld worden de vakantieuren van de 10 werknemers bijgewerkt met de vroegste huurdatums.

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

Voorbeelden: Azure Synapse Analytics and Analytics Platform System (PDW)

In het volgende voorbeeld worden de bovenste 31 rijen geretourneerd die overeenkomen met de querycriteria. De ORDER BY component zorgt ervoor dat de 31 geretourneerde rijen de eerste 31 rijen zijn op basis van een alfabetische volgorde van de LastName kolom.

Gebruik TOP zonder bindingen op te geven.

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

Resultaat: 31 rijen worden geretourneerd.

Gebruik TOPom WITH TIESop te geven.

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

Resultaat: 33 rijen worden geretourneerd, omdat drie werknemers met de naam Brown tie voor de 31e rij.