Compartilhar via


TOP (Transact-SQL)

Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada de SQL do AzureAzure Synapse AnalyticsAnalytics Platform System (PDW)Ponto de extremidade de análise de SQL no Microsoft FabricWarehouse no Microsoft FabricBanco de Dados SQL no Microsoft Fabric

Limita as linhas retornadas em um conjunto de resultados de consulta a um número ou percentual de linhas no SQL Server. Quando você usa TOP com a cláusula ORDER BY, o conjunto de resultados é limitado ao primeiro n número de linhas ordenadas. Caso contrário, TOP retorna o primeiro n número de linhas em uma ordem indefinida. Use esta cláusula para especificar o número de linhas retornadas de uma instrução SELECT. Ou use TOP para especificar as linhas afetadas por uma instrução INSERT, UPDATE, MERGEou DELETE.

Convenções de sintaxe de Transact-SQL

Sintaxe

Sintaxe para SQL Server e Banco de Dados SQL do Azure:

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

Sintaxe do PDW (Azure Synapse Analytics and Analytics Platform System):

[
    TOP ( expression )
    [ WITH TIES ]
]

Argumentos

expressão

A expressão numérica que especifica o número de linhas a serem retornadas. expressão é convertida implicitamente em um valor de de flutuação se você especificar . Caso contrário, expression é convertido em bigint.

PERCENT

Indica que a consulta retorna apenas a primeira porcentagem de linhas da expression do conjunto de resultados. Os valores fracionários são arredondados até o próximo valor inteiro.

WITH TIES

Retorna duas ou mais linhas associadas ao último lugar do conjunto de resultados limitado. Você deve usar esse argumento com a cláusula ORDER BY. WITH TIES pode fazer com que mais linhas sejam retornadas do que o valor especificado na expressão . Por exemplo, se expressão estiver definida como 5 mas mais duas linhas corresponderem aos valores das colunas ORDER BY na linha 5, o conjunto de resultados conterá sete linhas.

Você pode especificar a cláusula TOP com o argumento WITH TIES somente em instruções SELECT e somente se também especificar a cláusula ORDER BY. A ordem retornada de registros vinculados é arbitrária. ORDER BY não afeta essa regra.

Práticas recomendadas

Em uma instrução SELECT, sempre use uma cláusula ORDER BY com a cláusula TOP. Essa é a única maneira de indicar previsivelmente quais linhas são afetadas por TOP.

Use OFFSET e FETCH na cláusula ORDER BY em vez da cláusula TOP para implementar uma solução de paginação de consulta. Uma solução de paginação (ou seja, enviar partes ou páginas de dados para o cliente) é mais fácil de implementar usando cláusulas OFFSET e FETCH. Para obter mais informações, consulte CLÁUSULA SELECT – ORDER BY.

Use TOP (ou OFFSET e FETCH) em vez de SET ROWCOUNT para limitar o número de linhas retornadas. Esses métodos são preferenciais em vez de usar SET ROWCOUNT pelos seguintes motivos:

  • Como parte de uma instrução SELECT, o otimizador de consulta pode considerar o valor da expressão nas cláusulas TOP ou FETCH durante a otimização da consulta. Como você usa SET ROWCOUNT fora de uma instrução que executa uma consulta, seu valor não pode ser considerado em um plano de consulta.

Suporte à compatibilidade

Para compatibilidade com versões anteriores, os parênteses são opcionais em instruções SELECT se a expressão for uma constante inteiro. Recomendamos que você sempre use parênteses para TOP em instruções SELECT. Isso fornece consistência com seu uso necessário em instruções INSERT, UPDATE, MERGEe DELETE.

Interoperabilidade

A expressão TOP não afeta instruções que podem ser executadas por causa de um gatilho. As tabelas inserted e deleted nos gatilhos retornam apenas as linhas realmente afetadas pelas instruções INSERT, UPDATE, MERGEou DELETE. Por exemplo, se um INSERT TRIGGER for acionado como resultado de uma instrução INSERT que usou uma cláusula TOP.

O SQL Server permite a atualização de linhas através de exibições. Como você pode incluir a cláusula TOP na definição de exibição, determinadas linhas poderão desaparecer da exibição se as linhas não atenderem mais aos requisitos da expressão TOP devido a uma atualização.

Quando especificada na instrução MERGE, a cláusula TOP aplica-se depois que a tabela de origem inteira e toda a tabela de destino são unidas. E as linhas unidas que não se qualificam para uma ação de inserção, atualização ou exclusão são removidas. A cláusula TOP reduz ainda mais o número de linhas unidas ao valor especificado e as ações de inserção, atualização ou exclusão se aplicam às linhas unidas restantes de forma não ordenada. Ou seja, não há nenhuma ordem na qual as linhas são distribuídas entre as ações definidas nas cláusulas WHEN. Por exemplo, se a especificação de TOP (10) afetar 10 linhas, sete dessas linhas poderão ser atualizadas e três inseridas. Ou, um pode ser excluído, cinco atualizados e quatro inseridos e assim por diante. Como a instrução MERGE faz uma verificação de tabela completa das tabelas de origem e de destino, o desempenho de E/S pode ser afetado quando você usa a cláusula TOP para modificar uma tabela grande criando vários lotes. Nesse cenário, é importante garantir que todos os lotes sucessivos se destinem a novas linhas.

Tenha cuidado ao especificar a cláusula TOP em uma consulta que contém um operador UNION, UNION ALL, EXCEPTou INTERSECT. É possível escrever uma consulta que retorna resultados inesperados porque a ordem na qual as cláusulas TOP e ORDER BY são processadas logicamente nem sempre é intuitiva quando esses operadores são usados em uma operação de seleção. Por exemplo, a partir da tabela e dos dados a seguir, suponha que você queira retornar o carro vermelho e o carro azul mais baratos. Isto é, o automóvel vermelho e a van azul.

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

Para obter esses resultados, você poderia gravar a consulta a seguir.

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

Aqui está o conjunto de resultados.

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

Os resultados inesperados são retornados porque a cláusula TOP é executada logicamente antes da cláusula ORDER BY, que classifica os resultados do operador (UNION ALL nesse caso). Assim, a consulta anterior retorna qualquer carro vermelho e qualquer carro azul e, em seguida, ordena o resultado dessa união pelo preço. O exemplo a seguir mostra o método correto de gravar essa consulta para obter o resultado desejado.

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

Ao usar TOP e ORDER BY em uma operação de subseleção, verifique se os resultados da cláusula ORDER BY são aplicados à cláusula TOP e não à classificação do resultado da operação de UNION.

Aqui está o conjunto de resultados.

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

Limitações

Quando você usa TOP com INSERT, UPDATE, MERGEou DELETE, as linhas referenciadas não são organizadas em nenhuma ordem. E não é possível especificar diretamente a cláusula ORDER BY nessas instruções. Se você precisar usar TOP para inserir, excluir ou modificar linhas em uma ordem cronológica significativa, use TOP com uma cláusula ORDER BY especificada em uma instrução de subseleção. Consulte a seção Exemplos neste artigo.

Você não pode usar TOP em instruções UPDATE ou DELETE em exibições particionadas.

Não é possível combinar TOP com OFFSET e FETCH na mesma expressão de consulta (no mesmo escopo de consulta). Para obter mais informações, consulte CLÁUSULA SELECT – ORDER BY.

Exemplos

Os exemplos de código Transact-SQL neste artigo usam o banco de dados de exemplo AdventureWorks2022 ou AdventureWorksDW2022, que você pode baixar na home page Microsoft SQL Server Samples and Community Projects.

Categoria Elementos de sintaxe em destaque
Sintaxe básica TOP * PERCENT
Incluindo valores de empate WITH TIES
Limitando as linhas afetadas por DELETE, INSERT ou UPDATE DELETE, INSERT, UPDATE

Sintaxe básica

Exemplos nesta seção demonstram a funcionalidade básica da cláusula ORDER BY usando a sintaxe mínima necessária.

a. Usar TOP com um valor constante

Os exemplos a seguir usam um valor constante para especificar o número de funcionários que são retornados no conjunto de resultados da consulta. No primeiro exemplo, as primeiras 10 linhas indefinidas são retornadas porque uma cláusula ORDER BY não é usada. No segundo exemplo, uma cláusula ORDER BY é usada para retornar os 10 principais funcionários contratados recentemente.

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. Usar TOP com uma variável

O exemplo a seguir usa uma variável para especificar o número de funcionários que são retornados no conjunto de resultados da consulta.

USE AdventureWorks2022;
GO

DECLARE @p AS INT = 10;

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

C. Especificar uma porcentagem

O exemplo a seguir usa PERCENT para especificar o número de funcionários retornados no conjunto de resultados da consulta. Há 290 funcionários na tabela HumanResources.Employee. Como cinco por cento de 290 é um valor fracionário, o valor é arredondado para o próximo número inteiro.

USE AdventureWorks2022;
GO

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

Incluir valores de empate

a. Usar WITH TIES para incluir linhas que correspondem aos valores na última linha

O exemplo a seguir obtém os primeiros 10 por cento de todos os funcionários com o salário mais alto e os retorna em ordem descendente, de acordo com seu salário. Especificar WITH TIES assegura que todos os funcionários que recebem salários iguais ao salário mais baixo retornado (a última linha) também serão incluídos no conjunto de resultados, mesmo que isso exceda 10 por cento dos funcionários.

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

Limitar as linhas afetadas por DELETE, INSERT ou UPDATE

a. Usar TOP para limitar o número de linhas excluídas

Quando você usa uma cláusula TOP (<n>) com DELETE, a operação de exclusão é feita em uma seleção indefinida de n número de linhas. Ou seja, a instrução DELETE escolhe qualquer número (n) de linhas que atendam aos critérios definidos na cláusula WHERE. O exemplo a seguir exclui 20 linhas da tabela PurchaseOrderDetail que têm datas de conclusão anteriores a 1º de julho de 2002.

USE AdventureWorks2022;
GO

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

Se você quiser usar TOP para excluir linhas em uma ordem cronológica significativa, use TOP com ORDER BY em uma instrução de subseleção. A consulta a seguir exclui as 10 linhas da tabela PurchaseOrderDetail que têm as primeiras datas de vencimento. Para garantir que apenas 10 linhas sejam excluídas, a coluna especificada na instrução de subseleção (PurchaseOrderID) é a chave primária da tabela. Usar uma coluna não chave na instrução subseleção poderá resultar na exclusão de mais de 10 linhas se a coluna especificada contiver valores duplicados.

USE AdventureWorks2022;
GO

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

B. Usar TOP para limitar o número de linhas inseridas

O exemplo a seguir cria a tabela EmployeeSales e insere nela o nome e os dados de vendas desde o início do ano dos cinco funcionários principais da tabela HumanResources.Employee. A instrução INSERT escolhe as cinco linhas retornadas pela instrução SELECT que atendam aos critérios definidos na cláusula WHERE. A cláusula OUTPUT exibe as linhas inseridas na tabela EmployeeSales. A cláusula ORDER BY na instrução SELECT não é usada para determinar os cinco principais funcionários.

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

Se você quiser usar TOP para inserir linhas em uma ordem cronológica significativa, use TOP com ORDER BY em uma instrução de subseleção. O exemplo a seguir mostra como fazer isso. A cláusula OUTPUT exibe as linhas inseridas na tabela EmployeeSales. Os cinco principais funcionários agora são inseridos com base nos resultados da cláusula ORDER BY em vez de linhas indefinidas.

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. Usar TOP para limitar o número de linhas atualizadas

O exemplo a seguir usa a cláusula TOP para atualizar linhas em uma tabela. Quando você usa uma cláusula TOP (<n>) com UPDATE, a operação de atualização é executada em um número indefinido de linhas. Ou seja, a instrução UPDATE escolhe qualquer número (n) de linhas que atendam aos critérios definidos na cláusula WHERE. O exemplo a seguir atribui 10 clientes de um vendedor para outro.

USE AdventureWorks2022;

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

Se você precisar usar TOP para aplicar atualizações em uma cronologia significativa, deverá usar TOP junto com ORDER BY em uma instrução de subseleção. O exemplo a seguir atualiza as horas de férias dos 10 funcionários com as datas de contratação mais antigas.

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

Exemplos: Azure Synapse Analytics e PDW (Analytics Platform System)

O exemplo a seguir retorna as primeiras 31 linhas que correspondem aos critérios de consulta. A cláusula ORDER BY garante que as 31 linhas retornadas sejam as primeiras 31 linhas com base em uma ordenação alfabética da coluna LastName.

Usando TOP sem especificar vínculos.

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

Resultado: 31 linhas são retornadas.

Usando TOP, especificando WITH TIES.

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

Resultado: 33 linhas são retornadas, pois três funcionários chamados Brown empate para a 31ª linha.