Udostępnij za pośrednictwem


TOP (Transact-SQL)

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)punkt końcowy analizy SQL w usłudze Microsoft FabricWarehouse w usłudze Microsoft FabricSQL Database w usłudze Microsoft Fabric

Ogranicza wiersze zwracane w zestawie wyników zapytania do określonej liczby wierszy lub procentu wierszy w programie SQL Server. Jeśli używasz TOP z klauzulą ORDER BY, zestaw wyników jest ograniczony do pierwszej n liczby uporządkowanych wierszy. W przeciwnym razie TOP zwraca pierwszą n liczbę wierszy w niezdefiniowanej kolejności. Użyj tej klauzuli, aby określić liczbę wierszy zwróconych z instrukcji SELECT. Możesz też użyć TOP, aby określić wiersze, których dotyczy instrukcja INSERT, UPDATE, MERGElub DELETE.

Transact-SQL konwencje składni

Składnia

Składnia dla programu SQL Server i usługi Azure SQL Database:

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

Składnia dla usługi Azure Synapse Analytics and Analytics Platform System (PDW):

[
    TOP ( expression )
    [ WITH TIES ]
]

Argumenty

wyrażenia

Wyrażenie liczbowe określające liczbę wierszy do zwrócenia. wyrażenie jest niejawnie konwertowane na wartość zmiennoprzecinkową , jeśli określisz wartość PERCENT. W przeciwnym razie wyrażenie jest konwertowane na bigint.

PROCENT

Wskazuje, że zapytanie zwraca tylko pierwsze wyrażenie procent wierszy z zestawu wyników. Wartości ułamkowe są zaokrąglane w górę do następnej wartości całkowitej.

Z KRAWATAMI

Zwraca co najmniej dwa wiersze, które są związane na ostatnim miejscu w ograniczonym zestawie wyników. Należy użyć tego argumentu z klauzulą ORDER BY. WITH TIES może spowodować zwrócenie większej liczby wierszy niż wartość określona w wyrażeniu . Jeśli na przykład wyrażenie jest ustawione na , ale dwa kolejne wiersze są zgodne z wartościami kolumn w wierszu 5, zestaw wyników zawiera siedem wierszy.

Można określić klauzulę TOP z argumentem WITH TIES tylko w instrukcjach SELECT i tylko wtedy, gdy określisz również klauzulę ORDER BY. Zwracana kolejność wiązania rekordów jest dowolna. ORDER BY nie ma wpływu na tę regułę.

Najlepsze rozwiązania

W instrukcji SELECT zawsze należy użyć klauzuli ORDER BY z klauzulą TOP. Jest to jedyny sposób przewidywania, na które wiersze mają wpływ TOP.

Użyj OFFSET i FETCH w klauzuli ORDER BY zamiast klauzuli TOP, aby zaimplementować rozwiązanie do stronicowania zapytań. Rozwiązanie stronicowania (czyli wysyłanie fragmentów lub stron danych do klienta) jest łatwiejsze do zaimplementowania przy użyciu klauzul OFFSET i FETCH. Aby uzyskać więcej informacji, zobacz SELECT — ORDER BY, klauzula.

Użyj TOP (lub OFFSET i FETCH) zamiast SET ROWCOUNT, aby ograniczyć liczbę zwracanych wierszy. Te metody są preferowane w przypadku używania SET ROWCOUNT z następujących powodów:

  • W ramach instrukcji SELECT optymalizator zapytań może rozważyć wartość wyrażenia w klauzulach TOP lub FETCH podczas optymalizacji zapytań. Ponieważ używasz SET ROWCOUNT poza instrukcją, która uruchamia zapytanie, jej wartość nie może być brana pod uwagę w planie zapytania.

Obsługa zgodności

W przypadku zgodności z poprzednimi wersjami nawiasy są opcjonalne w instrukcjach SELECT, jeśli wyrażenie jest stałą całkowitą. Zalecamy, aby zawsze używać nawiasów dla TOP w instrukcjach SELECT. Zapewnia to spójność z wymaganym użyciem w instrukcjach INSERT, UPDATE, MERGEi DELETE.

Współdziałanie

Wyrażenie TOP nie ma wpływu na instrukcje, które mogą być uruchamiane z powodu wyzwalacza. Tabele inserted i deleted w wyzwalaczach zwracają tylko wiersze, których naprawdę dotyczą instrukcje INSERT, UPDATE, MERGElub DELETE. Jeśli na przykład INSERT TRIGGER zostanie wyzwolony w wyniku instrukcji INSERT, która użyła klauzuli TOP.

Program SQL Server umożliwia aktualizowanie wierszy za pośrednictwem widoków. Ponieważ można uwzględnić klauzulę TOP w definicji widoku, niektóre wiersze mogą zniknąć z widoku, jeśli wiersze nie spełniają już wymagań wyrażenia TOP z powodu aktualizacji.

Po określeniu w instrukcji MERGE klauzula TOP ma zastosowanie po całej tabeli źródłowej, a cała tabela docelowa zostanie sprzężona. A sprzężone wiersze, które nie kwalifikują się do akcji wstawiania, aktualizowania lub usuwania, są usuwane. Klauzula TOP dodatkowo zmniejsza liczbę sprzężonych wierszy do określonej wartości, a akcje wstawiania, aktualizowania lub usuwania dotyczą pozostałych sprzężonych wierszy w sposób nieurządkowany. Oznacza to, że nie ma kolejności, w której wiersze są dystrybuowane między akcje zdefiniowane w klauzulach WHEN. Na przykład jeśli określenie TOP (10) ma wpływ na 10 wierszy, siedem z tych wierszy może zostać zaktualizowanych i trzy wstawione. Można też usunąć, zaktualizować pięć i cztery wstawione itd. Ponieważ instrukcja MERGE wykonuje pełne skanowanie tabeli zarówno tabel źródłowych, jak i docelowych, wydajność operacji we/wy może mieć wpływ na użycie klauzuli TOP w celu zmodyfikowania dużej tabeli przez utworzenie wielu partii. W tym scenariuszu należy upewnić się, że wszystkie kolejne partie są przeznaczone dla nowych wierszy.

Należy zachować ostrożność podczas określania klauzuli TOP w zapytaniu zawierającym operator UNION, UNION ALL, EXCEPTlub INTERSECT. Istnieje możliwość zapisania zapytania zwracającego nieoczekiwane wyniki, ponieważ kolejność przetwarzania klauzul TOP i ORDER BY nie zawsze jest intuicyjna, gdy te operatory są używane w operacji wybierania. Na przykład biorąc pod uwagę poniższą tabelę i dane, załóżmy, że chcesz zwrócić najtańszy samochód czerwony i najmniej drogi niebieski samochód. Oznacza to, czerwony sedan i niebieski van.

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

Aby osiągnąć te wyniki, możesz napisać następujące zapytanie.

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

Oto zestaw wyników.

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

Zwracane są nieoczekiwane wyniki, ponieważ klauzula TOP jest logicznie uruchamiana przed klauzulą ORDER BY, która sortuje wyniki operatora (UNION ALL w tym przypadku). Dlatego poprzednie zapytanie zwraca jeden czerwony samochód i dowolny niebieski samochód, a następnie zamawia wynik tego związku według ceny. W poniższym przykładzie pokazano poprawną metodę pisania tego zapytania w celu uzyskania żądanego wyniku.

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

Używając TOP i ORDER BY w operacji podwybierz, upewnij się, że wyniki klauzuli ORDER BY są stosowane do klauzuli TOP, a nie sortowania wyniku operacji UNION.

Oto zestaw wyników.

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

Ograniczenia

W przypadku używania TOP z INSERT, UPDATE, MERGElub DELETE, przywoływani wiersze nie są rozmieszczane w żadnej kolejności. Nie można również bezpośrednio określić klauzuli ORDER BY w tych instrukcjach. Jeśli musisz użyć TOP do wstawiania, usuwania lub modyfikowania wierszy w znaczącej kolejności chronologicznej, użyj TOP z klauzulą ORDER BY określoną w instrukcji subselect. Zobacz sekcję przykłady w tym artykule.

Nie można używać TOP w instrukcjach UPDATE ani DELETE w widokach partycjonowanych.

Nie można połączyć TOP z OFFSET i FETCH w tym samym wyrażeniu zapytania (w tym samym zakresie zapytania). Aby uzyskać więcej informacji, zobacz SELECT — ORDER BY, klauzula.

Przykłady

Przykłady kodu Transact-SQL w tym artykule korzystają z przykładowej bazy danych AdventureWorks2022 lub AdventureWorksDW2022, którą można pobrać ze strony głównej Przykłady programu Microsoft SQL Server i projekty społeczności.

Kategoria Polecane elementy składni
podstawowa składnia TOP * PERCENT
dołączanie wartości wiązania WITH TIES
ograniczanie wierszy, których dotyczy usuwanie, wstawianie lub UPDATE DELETE, INSERT, UPDATE

Składnia podstawowa

Przykłady w tej sekcji przedstawiają podstawowe funkcje klauzuli ORDER BY przy użyciu minimalnej wymaganej składni.

A. Używanie funkcji TOP z wartością stałą

W poniższych przykładach użyto stałej wartości, aby określić liczbę pracowników zwracanych w zestawie wyników zapytania. W pierwszym przykładzie zwracane są pierwsze 10 niezdefiniowanych wierszy, ponieważ nie jest używana klauzula ORDER BY. W drugim przykładzie jest używana klauzula ORDER BY, aby zwrócić 10 ostatnio zatrudnionych pracowników.

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. Używanie funkcji TOP ze zmienną

W poniższym przykładzie użyto zmiennej w celu określenia liczby pracowników zwracanych w zestawie wyników zapytania.

USE AdventureWorks2022;
GO

DECLARE @p AS INT = 10;

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

C. Określanie wartości procentowej

W poniższym przykładzie użyto PERCENT, aby określić liczbę pracowników zwracanych w zestawie wyników zapytania. W tabeli HumanResources.Employee znajduje się 290 pracowników. Ponieważ pięć procent 290 jest wartością ułamkową, wartość jest zaokrąglona do następnej liczby całkowitej.

USE AdventureWorks2022;
GO

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

Uwzględnij wartości wiązania

A. Użyj funkcji WITH TIES, aby uwzględnić wiersze zgodne z wartościami w ostatnim wierszu

Poniższy przykład pobiera najwyższą 10 procent wszystkich pracowników z najwyższym wynagrodzeniem i zwraca je w kolejności malejącej zgodnie z ich wynagrodzeniem. Określenie WITH TIES zapewnia, że pracownicy z wynagrodzeniami równymi najniższej pensji zwróconej (ostatni wiersz) są również uwzględniani w zestawie wyników, nawet jeśli przekroczy 10 procent pracowników.

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

Ogranicz wiersze, których dotyczy operacja DELETE, INSERT lub UPDATE

A. Użyj funkcji TOP, aby ograniczyć liczbę usuniętych wierszy

W przypadku używania klauzuli TOP (<n>) z DELETEoperacja usuwania jest wykonywana w niezdefiniowanym zaznaczeniu n liczby wierszy. Oznacza to, że instrukcja DELETE wybiera dowolną (n) liczbę wierszy spełniających kryteria zdefiniowane w klauzuli WHERE. Poniższy przykład usuwa 20 wierszy z tabeli PurchaseOrderDetail, które mają daty ukończenia wcześniejsze niż 1 lipca 2002 r.

USE AdventureWorks2022;
GO

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

Jeśli chcesz użyć TOP do usunięcia wierszy w znaczącej kolejności chronologicznej, użyj TOP z ORDER BY w instrukcji subselect. Poniższe zapytanie usuwa 10 wierszy tabeli PurchaseOrderDetail, które mają najwcześniejsze daty ukończenia. Aby upewnić się, że usunięto tylko 10 wierszy, kolumna określona w instrukcji subselect (PurchaseOrderID) jest kluczem podstawowym tabeli. Użycie kolumny innej niż klucz w instrukcji subselect może spowodować usunięcie więcej niż 10 wierszy, jeśli określona kolumna zawiera zduplikowane wartości.

USE AdventureWorks2022;
GO

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

B. Użyj funkcji TOP, aby ograniczyć liczbę wstawionych wierszy

Poniższy przykład tworzy tabelę EmployeeSales i wstawia nazwę i dane sprzedaży od początku roku dla pięciu najlepszych pracowników z tabeli HumanResources.Employee. Instrukcja INSERT wybiera pięć wierszy zwróconych przez instrukcję SELECT, które spełniają kryteria zdefiniowane w klauzuli WHERE. Klauzula OUTPUT wyświetla wiersze wstawione do tabeli EmployeeSales. Klauzula ORDER BY w instrukcji SELECT nie jest używana do określania pięciu najlepszych pracowników.

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

Jeśli chcesz użyć TOP do wstawienia wierszy w znaczącej kolejności chronologicznej, użyj TOP z ORDER BY w instrukcji subselect. W poniższym przykładzie pokazano, jak to zrobić. Klauzula OUTPUT wyświetla wiersze wstawione do tabeli EmployeeSales. Pięciu najlepszych pracowników jest teraz wstawionych na podstawie wyników klauzuli ORDER BY zamiast niezdefiniowanych wierszy.

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. Użyj funkcji TOP, aby ograniczyć liczbę zaktualizowanych wierszy

W poniższym przykładzie użyto klauzuli TOP w celu zaktualizowania wierszy w tabeli. W przypadku używania klauzuli TOP (<n>) z UPDATEoperacja aktualizacji jest uruchamiana na niezdefiniowanej liczbie wierszy. Oznacza to, że instrukcja UPDATE wybiera dowolną (n) liczbę wierszy spełniających kryteria zdefiniowane w klauzuli WHERE. W poniższym przykładzie przypisano 10 klientów od jednego sprzedawcy do innego.

USE AdventureWorks2022;

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

Jeśli musisz użyć TOP do stosowania aktualizacji w znaczącej chronologii, musisz użyć TOP razem z ORDER BY w instrukcji subselect. Poniższy przykład aktualizuje godziny urlopu 10 pracowników z najwcześniejszymi datami zatrudnienia.

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

Przykłady: Azure Synapse Analytics and Analytics Platform System (PDW)

Poniższy przykład zwraca 31 pierwszych wierszy spełniających kryteria zapytania. Klauzula ORDER BY gwarantuje, że 31 zwracanych wierszy to pierwsze 31 wierszy na podstawie kolejności alfabetycznej kolumny LastName.

Używanie TOP bez określania powiązań.

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

Wynik: zwracane są 31 wierszy.

Za pomocą TOPokreśl WITH TIES.

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

Wynik: zwracane są 33 wiersze, ponieważ trzech pracowników nazwanych Brown remisu dla 31 wiersza.