Sdílet prostřednictvím


TOP (Transact-SQL)

platí pro:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)koncový bod SQL Analytics ve službě Microsoft FabricWarehouse v Microsoft Fabricdatabáze SQL v Microsoft Fabric

Omezí řádky vrácené v sadě výsledků dotazu na zadaný počet řádků nebo procento řádků v SQL Serveru. Při použití TOP s klauzulí ORDER BY je sada výsledků omezena na první n počet seřazených řádků. V opačném případě TOP vrátí první n počet řádků v nedefinované pořadí. Pomocí této klauzule můžete určit počet řádků vrácených z příkazu SELECT. Nebo můžete pomocí TOP určit řádky ovlivněné příkazem INSERT, UPDATE, MERGEnebo DELETE.

Transact-SQL konvence syntaxe

Syntax

Syntaxe pro SQL Server a Azure SQL Database:

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

Syntaxe pro Systém platformy Azure Synapse Analytics a Analytics (PDW):

[
    TOP ( expression )
    [ WITH TIES ]
]

Argumenty

výrazu

Číselný výraz, který určuje počet řádků, které se mají vrátit. výraz je implicitně převeden na hodnotu float pokud zadáte PERCENT. V opačném případě se výraz převede na bigint.

PROCENTO

Označuje, že dotaz vrátí pouze první výraz procent řádků ze sady výsledků. Desetinné hodnoty se zaokrouhlují nahoru na další celočíselnou hodnotu.

S VAZBAMI

Vrátí dva nebo více řádků, které spojují poslední místo v omezené sadě výsledků. Tento argument musíte použít s klauzulí ORDER BY. WITH TIES může způsobit vrácení více řádků, než je hodnota zadaná ve výrazu . Pokud je například výraz nastaven na 5 ale dva další řádky odpovídají hodnotám ORDER BY sloupců v řádku 5, sada výsledků obsahuje sedm řádků.

Klauzuli TOP můžete zadat pomocí argumentu WITH TIES pouze v příkazech SELECT a pouze v případě, že zadáte také klauzuli ORDER BY. Vrácené pořadí vázaných záznamů je libovolné. ORDER BY toto pravidlo neovlivní.

Osvědčené postupy

V příkazu SELECT vždy použijte klauzuli ORDER BY s klauzulí TOP. Toto je jediný způsob, jak předpovědět, které řádky jsou ovlivněny TOP.

K implementaci řešení stránkování dotazů použijte OFFSET a FETCH v klauzuli ORDER BY místo klauzule TOP. Stránkovací řešení (tj. odesílání bloků dat nebo stránek dat klientovi) je snazší implementovat pomocí OFFSET a FETCH klauzulí. Další informace naleznete v tématu SELECT - ORDER BY klauzule.

Pokud chcete omezit počet vrácených řádků, použijte místo SET ROWCOUNTTOP (nebo OFFSET a FETCH). Tyto metody se preferují před používáním SET ROWCOUNT z následujících důvodů:

  • Jako součást příkazu SELECT může optimalizátor dotazů při optimalizaci dotazů zvážit hodnotu výrazu v klauzulích TOP nebo FETCH. Vzhledem k tomu, že používáte SET ROWCOUNT mimo příkaz, který spouští dotaz, nelze jeho hodnotu považovat za plán dotazu.

Podpora kompatibility

Kvůli zpětné kompatibilitě jsou závorky volitelné v příkazech SELECT, pokud je výraz celočíselnou konstantou. Doporučujeme vždy používat závorky pro TOP v příkazech SELECT. To zajišťuje konzistenci s požadovaným použitím v příkazech INSERT, UPDATE, MERGEa DELETE.

Interoperabilita

Výraz TOP nemá vliv na příkazy, které se můžou spouštět z důvodu triggeru. Tabulky inserted a deleted v triggerech vrátí pouze řádky, které jsou skutečně ovlivněny příkazy INSERT, UPDATE, MERGEnebo DELETE. Pokud se například INSERT TRIGGER aktivuje jako výsledek příkazu INSERT, který použil klauzuli TOP.

SQL Server umožňuje aktualizovat řádky prostřednictvím zobrazení. Vzhledem k tomu, že do definice zobrazení můžete zahrnout klauzuli TOP, můžou určité řádky z zobrazení zmizet, pokud řádky přestanou splňovat požadavky výrazu TOP kvůli aktualizaci.

Při zadání v příkazu MERGE se klauzule TOP použije po celé zdrojové tabulce a celé cílové tabulce. A spojené řádky, které nemají nárok na akci vložení, aktualizace nebo odstranění, se odeberou. Klauzule TOP dále snižuje počet spojených řádků na zadanou hodnotu a akce vložení, aktualizace nebo odstranění, které platí pro zbývající spojené řádky v neuspořádaném způsobu. To znamená, že řádky nejsou rozdělené mezi akce definované v klauzulích WHEN. Pokud například zadáte TOP (10) ovlivní 10 řádků, může být aktualizováno sedm z těchto řádků a tři vložené. Nebo jeden může být odstraněn, pět aktualizován a čtyři vloženy atd. Vzhledem k tomu, že příkaz MERGE provede úplnou kontrolu tabulky zdrojových i cílových tabulek, může být ovlivněn výkon vstupně-výstupních operací při použití klauzule TOP k úpravě velké tabulky vytvořením více dávek. V tomto scénáři je důležité zajistit, aby všechny následné dávky cílily na nové řádky.

Při zadávání klauzule TOP v dotazu, který obsahuje operátor UNION, UNION ALL, EXCEPTnebo INTERSECT, buďte opatrní. Dotaz, který vrací neočekávané výsledky, je možné napsat, protože pořadí, ve kterém jsou klauzule TOP a ORDER BY logicky zpracovány, není vždy intuitivní, když se tyto operátory používají v operaci select. Například vzhledem k následující tabulce a datům předpokládejme, že chcete vrátit nejméně drahé červené auto a nejméně drahé modré auto. To je červený sedan a modrá dodávka.

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

K dosažení těchto výsledků můžete napsat následující dotaz.

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

Tady je sada výsledků.

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

Neočekávané výsledky se vrátí, protože klauzule TOP logicky běží před klauzulí ORDER BY, která seřadí výsledky operátoru (UNION ALL v tomto případě). Předchozí dotaz tedy vrátí jakékoli červené auto a jakékoli modré auto a pak se vyřídí výsledek této sjednocení podle ceny. Následující příklad ukazuje správnou metodu zápisu tohoto dotazu, aby dosáhl požadovaného výsledku.

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

Použitím TOP a ORDER BY v operaci dílčího výběru zajistíte, že se výsledky klauzule ORDER BY použijí na klauzuli TOP a ne na řazení výsledku operace UNION.

Tady je sada výsledků.

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

Omezení

Pokud používáte TOP s INSERT, UPDATE, MERGEnebo DELETE, odkazované řádky nejsou uspořádány v žádném pořadí. A v těchto příkazech nemůžete přímo zadat klauzuli ORDER BY. Pokud potřebujete použít TOP k vložení, odstranění nebo úpravě řádků ve smysluplné chronologické pořadí, použijte TOP s klauzulí ORDER BY zadanou v příkazu subselect. Podívejte se na část Příklady v tomto článku.

V UPDATE nebo DELETE příkazů v rozdělených zobrazeních nemůžete použít TOP.

Nemůžete kombinovat TOP s OFFSET a FETCH ve stejném výrazu dotazu (ve stejném oboru dotazu). Další informace naleznete v tématu SELECT - ORDER BY klauzule.

Příklady

Ukázky kódu Transact-SQL v tomto článku používají AdventureWorks2022 nebo AdventureWorksDW2022 ukázkovou databázi, kterou si můžete stáhnout z domovské stránky ukázky Microsoft SQL Serveru a projekty komunity.

Kategorie Doporučené prvky syntaxe
základní syntaxe TOP * PERCENT
včetně hodnot vazby WITH TIES
omezení řádků ovlivněných příkazem DELETE, INSERT nebo UPDATE DELETE, INSERT, UPDATE

Základní syntaxe

Příklady v této části ukazují základní funkce klauzule ORDER BY pomocí minimální požadované syntaxe.

A. Použití top s konstantní hodnotou

Následující příklady používají konstantní hodnotu k určení počtu zaměstnanců vrácených v sadě výsledků dotazu. V prvním příkladu se vrátí prvních 10 nedefinovaných řádků, protože se nepoužívá klauzule ORDER BY. V druhém příkladu se klauzule ORDER BY používá k vrácení prvních 10 nedávno najatých zaměstnanců.

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. Použití top s proměnnou

Následující příklad používá proměnnou k určení počtu zaměstnanců vrácených v sadě výsledků dotazu.

USE AdventureWorks2022;
GO

DECLARE @p AS INT = 10;

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

C. Zadání procenta

Následující příklad používá PERCENT k určení počtu zaměstnanců vrácených v sadě výsledků dotazu. V tabulce HumanResources.Employee je 290 zaměstnanců. Protože pět procent z 290 je desetinná hodnota, hodnota se zaokrouhlí nahoru na další celé číslo.

USE AdventureWorks2022;
GO

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

Zahrnout hodnoty vazby

A. Použití funkce WITH TIES k zahrnutí řádků, které odpovídají hodnotám v posledním řádku

Následující příklad získá nejvyšší 10 procent všech zaměstnanců s nejvyšší mzdou a vrátí je sestupně podle jejich platu. Určení WITH TIES zajistí, aby zaměstnanci s platy, které se rovnají nejnižším vráceným platům (poslední řádek), byly také zahrnuty do sady výsledků, i když překročí 10 procent zaměstnanců.

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

Omezení řádků ovlivněných příkazem DELETE, INSERT nebo UPDATE

A. Omezení počtu odstraněných řádků pomocí funkce TOP

Pokud použijete klauzuli TOP (<n>) s DELETE, operace delete se provádí u nedefinovaného výběru n počtu řádků. To znamená, že příkaz DELETE zvolí libovolný počet řádků (n), které splňují kritéria definovaná v klauzuli WHERE. Následující příklad odstraní 20 řádky z tabulky PurchaseOrderDetail, které mají termín splnění dřívější než 1. července 2002.

USE AdventureWorks2022;
GO

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

Pokud chcete použít TOP k odstranění řádků ve smysluplné chronologickém pořadí, použijte TOP s ORDER BY v příkazu dílčího výběru. Následující dotaz odstraní 10 řádků tabulky PurchaseOrderDetail, které mají nejstarší termíny splnění. Pokud chcete zajistit, aby se odstranilo pouze 10 řádků, je sloupec zadaný v příkazu dílčího výběru (PurchaseOrderID) primárním klíčem tabulky. Použití jiného sloupce v příkazu dílčího výběru může vést k odstranění více než 10 řádků, pokud zadaný sloupec obsahuje duplicitní hodnoty.

USE AdventureWorks2022;
GO

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

B. Omezení počtu vložených řádků pomocí funkce TOP

Následující příklad vytvoří tabulku EmployeeSales a vloží údaje o prodeji od začátku roku pro prvních pět zaměstnanců z tabulky HumanResources.Employee. Příkaz INSERT zvolí libovolných pět řádků vrácených příkazem SELECT, který splňuje kritéria definovaná v klauzuli WHERE. Klauzule OUTPUT zobrazí řádky vložené do tabulky EmployeeSales. Klauzule ORDER BY v příkazu SELECT se nepoužívá k určení prvních pěti zaměstnanců.

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

Pokud chcete použít TOP k vložení řádků do smysluplného chronologického pořadí, použijte TOP s ORDER BY v příkazu dílčího výběru. Následující příklad ukazuje, jak to provést. Klauzule OUTPUT zobrazí řádky vložené do tabulky EmployeeSales. Prvních pět zaměstnanců se teď vloží na základě výsledků klauzule ORDER BY místo nedefinovaných řádků.

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. Omezení počtu aktualizovaných řádků pomocí funkce TOP

Následující příklad používá klauzuli TOP k aktualizaci řádků v tabulce. Pokud použijete klauzuli TOP (<n>) s UPDATE, operace aktualizace se spustí na nedefinovaný počet řádků. To znamená, že příkaz UPDATE zvolí libovolný počet řádků (n), které splňují kritéria definovaná v klauzuli WHERE. Následující příklad přiřadí 10 zákazníků z jednoho prodejce k jinému.

USE AdventureWorks2022;

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

Pokud potřebujete použít TOP k instalaci aktualizací ve smysluplné chronologii, musíte použít TOP společně s ORDER BY v příkazu dílčího výběru. Následující příklad aktualizuje pracovní dobu 10 zaměstnanců s nejstarším datem přijetí.

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

Příklady: Azure Synapse Analytics a Analytický platformový systém (PDW)

Následující příklad vrátí prvních 31 řádků, které odpovídají kritériím dotazu. Klauzule ORDER BY zajišťuje, že 31 vrácených řádků je prvních 31 řádků na základě abecedního pořadí sloupce LastName.

Použití TOP bez zadání vazeb.

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

Výsledek: Vrátí se 31 řádků.

Pomocí TOPzadejte WITH TIES.

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

Výsledek: Vrátí se 33 řádků, protože tři zaměstnanci s názvem Brown svázaní pro 31. řádek.