Поделиться через


TOP (Transact-SQL)

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure конечной точке аналитики платформы Аналитики Azure Synapse Analytics (PDW) в Microsoft Fabric Хранилище в Microsoft Fabric

Ограничивает число строк, возвращаемых в результирующем наборе запроса до заданного числа или процентного значения в SQL Server. Если вы используете TOP с предложением ORDER BY, в результирующий набор включаются только первые N строк отсортированного результата. В противном случае TOP возвращает N строк в неопределенном порядке. Это предложение позволяет ограничить число строк, возвращаемых инструкцией SELECT. Также TOP можно использовать для указания числа строк, затрагиваемых инструкциями INSERT, UPDATE, MERGE или DELETE.

Соглашения о синтаксисе Transact-SQL

Синтаксис

Ниже приводится синтаксис для SQL Server и Базы данных SQL Azure:

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

Ниже приводится синтаксис для Azure Synapse Analytics и Системы платформы аналитики (PDW):

[   
    TOP ( expression )   
    [ WITH TIES ]  
]  

Аргументы

выражение
Числовое выражение, определяющее количество возвращаемых строк. Если значение expression указано в процентах, оно неявно преобразуется в формат float. В противном случае expression преобразуется в формат bigint.

ПРОЦЕНТ
Указывает на то, что запрос возвращает только первые expression процентов строк из результирующего набора. Дробные значения округляются до следующего целого числа.

WITH TIES
Возвращает две или более строки, которые соперничают за последнее место в ограниченном результирующем наборе. Этот аргумент можно использовать только с предложением ORDER BY. В режиме WITH TIES количество возвращаемых строк может превысить значение expression. Например, если expression имеет значение 5 и существуют еще 2 строки с такими же значениями столбцов, указанных в предложении ORDER BY, что и у пятой строки, результирующий набор будет содержать 7 строк.

Предложение TOP можно сочетать с аргументом WITH TIES только в инструкциях SELECT, и только если вместе с ними задано предложение ORDER BY. Порядок возврата связанных записей произволен. ORDER BY не влияет на это правило.

Рекомендации

В инструкции SELECT всегда указывайте ORDER BY вместе с предложением TOP. Дело в том, что это единственный предсказуемый способ отбора строк предложением TOP.

Для реализации решения разбиения на страницы пользуйтесь предложениями OFFSET и FETCH в предложении ORDER BY, а не предложением TOP. Решение разбиения на страницы (т.е. постраничной выдачи данных клиенту) проще реализовать с помощью предложений OFFSET и FETCH. Дополнительные сведения см. в разделе Предложение ORDER BY (Transact-SQL).

Для ограничения числа возвращаемых строк пользуйтесь TOP (или OFFSET и FETCH), а не SET ROWCOUNT. Эти методы предпочтительнее, чем SET ROWCOUNT, по следующим причинам:

  • Являясь частью инструкции SELECT, оптимизатор запросов может принимать значение expression в предложениях TOP или FETCH во время оптимизации запроса. Так как SET ROWCOUNT используется вне инструкции, выполняющей запрос, значение не может быть учтено в плане запроса.

Поддержка совместимости

В целях обратной совместимости скобки в инструкции SELECT необязательны, если выражение является целочисленной константой. Мы рекомендуем всегда использовать круглые скобки для аргумента TOP в инструкциях SELECT. Такой подход обеспечивает согласованность с синтаксисом инструкций INSERT, UPDATE, MERGE и DELETE.

Совместимость

Выражение TOP не влияет на другие выражения, которые могут быть запущены триггером. Таблицы inserted и deleted в триггерах всегда возвращают только те строки, которые реально затронуты инструкциями INSERT, UPDATE, MERGE или DELETE. Например, если INSERT TRIGGER срабатывает в результате выполнения инструкции INSERT с предложением TOP,

то SQL Server позволяет обновлять строки через представления. Так как предложение TOP можно включать в определение представления, некоторые строки могут исчезнуть из представления после обновления, если они больше не соответствуют требованиям выражения TOP.

При использовании в инструкции MERGE предложение TOP применяется после соединения всей исходной таблицы и всей целевой таблицы, а также удаления соединенных строк, которые не соответствуют требованиям к вставке, обновлению или удалению. Предложение TOP дополнительно сокращает количество соединенных строк до указанного значения, а затем к оставшимся соединенным строкам применяются операции вставки, обновления или удаления без определенного порядка. Это означает, что порядок распределения строк по действиям, определенным в предложениях WHEN отсутствует. Например если TOP (10) в запросе затрагивает 10 строк, в их число могут попасть 7 обновляемых и 3 добавляемые строки. Или же 1 строка будет удаляемая, 5 обновляемых и 4 добавляемые строки либо любой другой вариант. Инструкция MERGE выполняет полное сканирование исходной и целевой таблиц, поэтому предложение TOP для изменения большой таблицы путем создания нескольких пакетов может снизить производительность ввода-вывода. В этом случае необходимо сделать так, чтобы все последующие пакеты содержали только новые строки.

Соблюдайте осторожность при использовании предложения TOP в запросе, содержащем операторы UNION, UNION ALL, EXCEPT и INTERSECT. Есть вероятность того, что результаты запроса будут непредсказуемыми из-за неожиданной логики обработки предложений TOP и ORDER BY в операции выбора. Например, исходя из следующих таблиц и данных, предположим, что необходимо вернуть самый недорогой красный и синий автомобили. Иными словами, красный седан и синий фургон.

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

Чтобы получить такие результаты, можно написать следующий запрос.

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    

Ниже приведен результирующий набор.

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

Возвращаются непредвиденные результаты, так как инструкция TOP логически выполняется раньше, чем предложение ORDER BY, которое сортирует результаты оператора (в данном случае UNION ALL). Таким образом, предыдущие запросы вернут произвольный красный и произвольный синий автомобили, а затем отсортируют результат такого объединения по цене. Следующий пример показывает, как правильно написать запрос, который позволит получить нужный результат.

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    

Использование TOP и ORDER BY во вложенной операции выбора гарантирует, что результаты предложения ORDER BY применяются к предложению TOP, а не к сортировке результата операции UNION.

Результирующий набор:

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

Ограничения

При использовании TOP в инструкции INSERT, UPDATE, MERGE или DELETE к строкам не применяется никакое упорядочение. Также вы не можете напрямую указать предложение ORDER BY в этих инструкциях. Если вы намерены использовать TOP, чтобы вставлять, удалять или изменять строки в определенном хронологическом порядке, добавьте TOP в предложение ORDER BY, включенное во вложенную инструкцию выборки. Подробнее см. раздел с примерами в этой статье.

Предложение TOP не может быть использовано в инструкциях UPDATE и DELETE для секционированных представлений.

TOP нельзя сочетать с OFFSET и FETCH в одном выражении запроса (в той же области запроса). Дополнительные сведения см. в разделе Предложение ORDER BY (Transact-SQL).

Примеры

Категория Используемые элементы синтаксиса
Основной синтаксис TOP * PERCENT
Включить равные значения WITH TIES
Ограничение числа строк, обрабатываемых инструкциями DELETE, INSERT и UPDATE DELETE * INSERT * UPDATE

Основной синтаксис

В примерах этого раздела показана базовая функциональность предложения ORDER BY с использованием минимально необходимого синтаксиса.

А. Использование ключевого слова TOP со значением константы

В следующих примерах константа указывает число сотрудников, возвращаемых в результирующем наборе запроса. В первом примере возвращаются 10 произвольных строк, так как отсутствует предложение ORDER BY. Во втором примере предложение ORDER BY возвращает 10 сотрудников, последними принятых на работу.

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 с переменной

В следующем примере переменная указывает число сотрудников, возвращаемых в результирующем наборе запроса.

USE AdventureWorks2022;  
GO  
DECLARE @p AS INT = 10;  
SELECT TOP(@p)JobTitle, HireDate, VacationHours  
FROM HumanResources.Employee  
ORDER BY VacationHours DESC;  
GO  

C. Указание процентов

В следующем примере PERCENT указывает число сотрудников, возвращаемых в результирующем наборе запроса. В таблице HumanResources.Employee содержится 290 сотрудников. 5 % от 290 является дробным числом, поэтому значение округляется вверх до целого числа.

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

Включить равные значения

А. Использование ключевого слова WITH TIES для включения строк, соответствующих значениям в последней строке

Следующий пример извлекает первые 10 процентов работников с наибольшей зарплатой и возвращает их в порядке убывания зарплаты. Выбор WITH TIES гарантирует, что в результирующий набор будут включены все работники с минимальной в этом списке зарплатой, даже если это приведет к превышению ограничения в 10 процентов работников.

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    

Ограничение числа строк, обрабатываемых инструкциями DELETE, INSERT и UPDATE

А. Ограничение числа удаляемых строк с помощью ключевого слова TOP

Если с инструкцией DELETE применяется предложение TOP (n), операция удаления производится с произвольной выборкой из n строк. Таким образом, инструкция DELETE выбирает любое число (n) строк, которые удовлетворяют условию, указанному в предложении WHERE. Следующий пример удаляет из таблицы PurchaseOrderDetail20 строк с датой завершения до 1 июля 2002 г.

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

Если вы намерены с помощью предложения TOP удалять строки в требуемом хронологическом порядке, включите TOP во вложенный запрос с предложением ORDER BY. Следующий запрос удаляет из таблицы PurchaseOrderDetail 10 строк, имеющих самую раннюю дату. Чтобы гарантировать удаление только 10 строк, столбец, указанный в инструкции подзапроса выборки (PurchaseOrderID) должен являться первичным ключом таблицы. Использование неключевого столбца в инструкции подзапроса выборки может привести к удалению более чем 10 строк, если указанный столбец содержит повторяющиеся значения.

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

B. Ограничение числа вставляемых строк с помощью ключевого слова TOP

В следующем примере создается таблица EmployeeSales и вставляется имя и данные о продажах за текущий год для 5 первых сотрудников из таблицы HumanResources.Employee. Инструкция INSERT выбирает из результата инструкции SELECT произвольные 5 строк, которые удовлетворяют условию, определенному в предложении WHERE. Предложение OUTPUT отображает строки, вставляемые в таблицу EmployeeSales. Обратите внимание, что в инструкции SELECT не используется предложение ORDER BY для определения 5 первых сотрудников.

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    

Если вы намерены с помощью предложения TOP добавлять строки в требуемом хронологическом порядке, включите TOP во вложенный запрос с предложением ORDER BY. Следующий пример показывает, как это сделать. Предложение OUTPUT отображает строки, вставляемые в таблицу EmployeeSales. Обратите внимание, что вставка данных о 5 первых сотрудниках выполняется теперь по результатам предложения ORDER BY, а не для произвольных строк.

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. Ограничение числа обновляемых строк с помощью ключевого слова TOP

В следующем примере предложение TOP используется для обновления строк в таблице. Если предложение TOP (n) используется с инструкцией UPDATE, операция обновления выполняется для неопределенного количества строк. Таким образом, инструкция UPDATE выбирает любое число (n) строк, которые удовлетворяют условию, указанному в предложении WHERE. В следующем примере 10 случайно выбранных заказчиков переназначаются от одного менеджера по продажам к другому.

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

Если нужно применить изменения с предложением TOP в определенной последовательности, укажите во вложенном запросе SELECT предложение ORDER BY. В следующем примере изменяется длительность отпуска для 10 сотрудников, имеющих наибольший стаж работы.

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  

Примеры: Azure Synapse Analytics и система платформы аналитики (PDW)

В приведенном ниже примере возвращаются первые строки (31), соответствующие условию запроса. Предложение ORDER BY гарантирует, что возвращается 31 строка в порядке сортировки столбца LastName по алфавиту.

Использование TOP без указания равных элементов.

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

Результат: возвращается 31 строка.

Использование TOP с указанием WITH TIES.

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

Результат: возвращаются 33 строки, так как три сотрудника с именем Браун галстук для 31-й строки.

См. также

SELECT (Transact-SQL)
INSERT (Transact-SQL)
UPDATE (Transact-SQL)
DELETE (Transact-SQL)
Предложение ORDER BY (Transact-SQL)
SET ROWCOUNT (Transact-SQL)
MERGE (Transact-SQL)