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
, MERGE
nebo DELETE
.
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 ROWCOUNT
TOP
(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íchTOP
neboFETCH
. Vzhledem k tomu, že používáteSET 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
, MERGE
a 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
, MERGE
nebo 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
, EXCEPT
nebo 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
, MERGE
nebo 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í TOP
zadejte 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.
Související obsah
-
SELECT (Transact-SQL) -
INSERT (Transact-SQL) -
UPDATE (Transact-SQL) -
DELETE (Transact-SQL) - SELECT – klauzule ORDER BY (Transact-SQL)
-
SET ROWCOUNT (Transact-SQL) -
MERGE (Transact-SQL)