Condividi tramite


TOP (Transact-SQL)

Si applica a: SQL Server database SQL di Azure Istanza gestita di SQL di Azure endpoint di analisi SQL di Azure Synapse AnalyticsPlatform System (PDW)in Microsoft FabricWarehouse nel database SQL di Microsoft Fabricin Microsoft Fabric

Limita le righe restituite nel set di risultati di una query a un numero specificato o a una percentuale di righe in SQL Server. Quando si usa TOP con la clausola ORDER BY, il set di risultati è limitato al primo n numero di righe ordinate. In caso contrario, TOP restituisce il primo n numero di righe in un ordine non definito. Utilizzare questa clausola per specificare il numero di righe restituite da un'istruzione SELECT. In alternativa, usare TOP per specificare le righe interessate da un'istruzione INSERT, UPDATE, MERGEo DELETE.

Convenzioni relative alla sintassi Transact-SQL

Sintassi

Sintassi per SQL Server e database SQL di Azure:

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

Sintassi per Azure Synapse Analytics and Analytics Platform System (PDW):

[
    TOP ( expression )
    [ WITH TIES ]
]

Argomenti

expression

Espressione numerica che specifica il numero di righe da restituire. 'espressione viene convertita in modo implicito in un valore float se si specifica . In caso contrario, l'argomento expression viene convertito in bigint.

PERCENT

Indica che la query restituisce solo la prima percentuale expression di righe dal set di risultati. I valori frazionari vengono arrotondati al valore intero più vicino.

WITH TIES

Restituisce due o più righe con valori equivalenti per l'ultima posizione del set di risultati limitato. È necessario utilizzare questo argomento con la clausola ORDER BY. WITH TIES potrebbe causare la restituzione di più righe rispetto al valore specificato nell'espressione . Ad esempio, se 'espressione è impostata su 5 ma altre due righe corrispondono ai valori delle colonne ORDER BY nella riga 5, il set di risultati contiene sette righe.

È possibile specificare la clausola TOP con l'argomento WITH TIES solo nelle istruzioni SELECT e solo se si specifica anche la clausola ORDER BY. L'ordine restituito per l'associazione dei record è arbitrario. ORDER BY non influisce su questa regola.

Procedure consigliate

In un'istruzione SELECT usare sempre una clausola ORDER BY con la clausola TOP. Questo è l'unico modo per indicare in modo prevedibile quali righe sono interessate da TOP.

Usare OFFSET e FETCH nella clausola ORDER BY anziché nella clausola TOP per implementare una soluzione di paging delle query. Una soluzione di paging, ovvero l'invio di blocchi o pagine di dati al client, è più semplice da implementare usando OFFSET e clausole FETCH. Per altre informazioni, vedere clausola SELECT - ORDER BY.

Usare TOP (o OFFSET e FETCH) anziché SET ROWCOUNT per limitare il numero di righe restituite. Questi metodi sono preferiti rispetto all'uso di SET ROWCOUNT per i motivi seguenti:

  • Come parte di un'istruzione SELECT, Query Optimizer può considerare il valore di expression nelle clausole TOP o FETCH durante l'ottimizzazione della query. Poiché si usa SET ROWCOUNT all'esterno di un'istruzione che esegue una query, il relativo valore non può essere considerato in un piano di query.

Supporto per la compatibilità

Per la compatibilità con le versioni precedenti, le parentesi sono facoltative nelle istruzioni SELECT se l'espressione è una costante integer. È consigliabile usare sempre le parentesi per TOP nelle istruzioni SELECT. In questo modo viene fornita coerenza con l'uso necessario nelle istruzioni INSERT, UPDATE, MERGEe DELETE .

Interoperabilità

L'espressione TOP non influisce sulle istruzioni che potrebbero essere eseguite a causa di un trigger. Le tabelle inserted e deleted nei trigger restituiscono solo le righe effettivamente interessate dalle istruzioni INSERT, UPDATE, MERGEo DELETE. Ad esempio, se un INSERT TRIGGER viene generato come risultato di un'istruzione INSERT che ha usato una clausola TOP.

Piattaforma di strumenti analitici consente l'aggiornamento delle righe attraverso le viste. Poiché è possibile includere la clausola TOP nella definizione della vista, alcune righe possono scomparire dalla visualizzazione se le righe non soddisfano più i requisiti dell'espressione TOP a causa di un aggiornamento.

Se specificato nell'istruzione MERGE, la clausola TOP si applica dopo l'intera tabella di origine e l'intera tabella di destinazione vengono unite in join. Le righe unite in join non qualificate per un'azione di inserimento, aggiornamento o eliminazione, inoltre, vengono rimosse. La clausola TOP riduce ulteriormente il numero di righe unite al valore specificato e le azioni di inserimento, aggiornamento o eliminazione si applicano alle righe unite in join rimanenti in modo non ordinato. Ciò significa che non esiste un ordine in cui le righe vengono distribuite tra le azioni definite nelle clausole WHEN. Ad esempio, se si specifica TOP (10) influisce su 10 righe, sette di queste righe potrebbero essere aggiornate e tre inserite. In alternativa, potrebbe essere eliminato, cinque aggiornati e quattro inseriti e così via. Poiché l'istruzione MERGE esegue un'analisi completa della tabella delle tabelle di origine e di destinazione, le prestazioni di I/O possono essere influenzate quando si usa la clausola TOP per modificare una tabella di grandi dimensioni creando più batch. In questo scenario è importante assicurarsi che tutti i batch successivi abbiano come destinazione nuove righe.

Prestare attenzione quando si specifica la clausola TOP in una query contenente un operatore UNION, UNION ALL, EXCEPTo INTERSECT. È possibile scrivere una query che restituisca risultati imprevisti perché l'ordine in cui le clausole TOP e ORDER BY vengono elaborate logicamente non è sempre intuitiva quando questi operatori vengono usati in un'operazione di selezione. Ad esempio, considerati i dati e la tabella seguenti, si supponga di voler ottenere come risultato la macchina rossa meno costosa e la macchina blu più costosa, ovvero la berlina rossa e il furgone blu.

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

Per ottenere questi risultati, è possibile scrivere la query seguente.

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

Ecco il set di risultati.

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

I risultati imprevisti vengono restituiti perché la clausola TOP viene eseguita logicamente prima della clausola ORDER BY, che ordina i risultati dell'operatore (UNION ALL in questo caso). La query precedente restituisce pertanto qualsiasi macchina rossa e qualsiasi macchina blu e quindi ordina il risultato dell'unione in base al prezzo. Nell'esempio seguente viene illustrato il metodo corretto per scrivere questa query per ottenere il risultato desiderato.

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

Utilizzando TOP e ORDER BY in un'operazione di selezione secondaria, assicurarsi che i risultati della clausola ORDER BY vengano applicati alla clausola TOP e non ordinare il risultato dell'operazione di UNION.

Ecco il set di risultati.

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

Limitazioni

Quando si usa TOP con INSERT, UPDATE, MERGEo DELETE, le righe a cui si fa riferimento non vengono disposte in alcun ordine. Inoltre, non è possibile specificare direttamente la clausola ORDER BY in queste istruzioni. Se è necessario usare TOP per inserire, eliminare o modificare righe in un ordine cronologico significativo, usare TOP con una clausola ORDER BY specificata in un'istruzione subselect. Vedere la sezione esempi di in questo articolo.

Non è possibile usare TOP nelle istruzioni UPDATE o DELETE nelle viste partizionate.

Non è possibile combinare TOP con OFFSET e FETCH nella stessa espressione di query (nello stesso ambito di query). Per altre informazioni, vedere clausola SELECT - ORDER BY.

Esempi

Gli esempi di codice Transact-SQL in questo articolo usano il database di esempio AdventureWorks2022 o AdventureWorksDW2022, che è possibile scaricare dalla home page Microsoft SQL Server Samples and Community Projects.

Categoria Elementi di sintassi inclusi
Sintassi di base TOP * PERCENT
Inclusione di valori equivalenti WITH TIES
Limitazione delle righe interessate da DELETE, INSERT o UPDATE DELETE, INSERT, UPDATE

Sintassi di base

Gli esempi in questa sezione illustrano le funzionalità di base della clausola ORDER BY usando la sintassi minima richiesta.

R. Usare TOP con un valore costante

Negli esempi seguenti viene utilizzato un valore costante per specificare il numero di dipendenti restituiti nel set di risultati della query. Nel primo esempio vengono restituite le prime 10 righe non predefinite perché non viene usata una clausola ORDER BY. Nel secondo esempio viene usata una clausola ORDER BY per restituire i primi 10 dipendenti assunti di recente.

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. Usare TOP con una variabile

Nell'esempio seguente viene utilizzata una variabile per specificare il numero di dipendenti restituiti nel set di risultati della query.

USE AdventureWorks2022;
GO

DECLARE @p AS INT = 10;

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

C. Specificare una percentuale

L'esempio seguente usa PERCENT per specificare il numero di dipendenti restituiti nel set di risultati della query. Nella tabella HumanResources.Employee sono presenti 290 dipendenti. Dato che il 5% di 290 è un valore frazionario, il valore viene arrotondato al numero intero successivo.

USE AdventureWorks2022;
GO

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

Includi valori di tie

R. Usare WITH TIES per includere righe corrispondenti ai valori nell'ultima riga

L'esempio seguente recupera il primo 10% di tutti i dipendenti con lo stipendio più alto e restituisce i dipendenti in ordine decrescente in base allo stipendio. Specificando WITH TIES, nel set di risultati vengono inclusi anche i dipendenti con stipendio pari allo stipendio più basso restituito (ultima riga), anche se in questo modo il set di risultati supera il 10% dei dipendenti.

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

Limitare le righe interessate da DELETE, INSERT o UPDATE

R. Usare TOP per limitare il numero di righe eliminate

Quando si usa una clausola TOP (<n>) con DELETE, l'operazione di eliminazione viene eseguita su una selezione non definita di n numero di righe. Ovvero, l'istruzione DELETE sceglie un numero qualsiasi (n) di righe che soddisfano i criteri definiti nella clausola WHERE. L'esempio seguente elimina 20 righe con scadenze precedenti al 1° luglio 2002 dalla tabella PurchaseOrderDetail.

USE AdventureWorks2022;
GO

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

Se si desidera usare TOP per eliminare righe in ordine cronologico significativo, usare TOP con ORDER BY in un'istruzione subselect. Tramite la query seguente vengono eliminate le 10 righe della tabella PurchaseOrderDetail contenenti le date di scadenza più imminenti. Per assicurarsi che vengano eliminate solo 10 righe, la colonna specificata nell'istruzione di selezione secondaria (PurchaseOrderID) è la chiave primaria della tabella. L'utilizzo di una colonna non chiave nell'istruzione subselect potrebbe comportare l'eliminazione di più di 10 righe se la colonna specificata contiene valori duplicati.

USE AdventureWorks2022;
GO

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

B. Usare TOP per limitare il numero di righe inserite

L'esempio seguente crea la tabella EmployeeSales e inserisce il nome e i dati sulle vendite da inizio anno per i primi cinque dipendenti della tabella HumanResources.Employee. L'istruzione INSERT sceglie le cinque righe restituite dall'istruzione SELECT che soddisfano i criteri definiti nella clausola WHERE. La clausola OUTPUT visualizza le righe inserite nella tabella EmployeeSales. La clausola ORDER BY nell'istruzione SELECT non viene usata per determinare i primi cinque dipendenti.

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 si desidera utilizzare TOP per inserire righe in un ordine cronologico significativo, usare TOP con ORDER BY in un'istruzione subselect. Nell'esempio seguente viene illustrato come eseguire questa operazione. La clausola OUTPUT visualizza le righe inserite nella tabella EmployeeSales. I primi cinque dipendenti vengono ora inseriti in base ai risultati della clausola ORDER BY anziché alle righe non predefinite.

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. Usare TOP per limitare il numero di righe aggiornate

Nell'esempio seguente viene utilizzata la clausola TOP per aggiornare le righe di una tabella. Quando si usa una clausola TOP (<n>) con UPDATE, l'operazione di aggiornamento viene eseguita su un numero non definito di righe. Ovvero, l'istruzione UPDATE sceglie un numero qualsiasi (n) di righe che soddisfano i criteri definiti nella clausola WHERE. Nell'esempio seguente vengono assegnati 10 clienti da un venditore a un altro.

USE AdventureWorks2022;

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

Se è necessario usare TOP per applicare gli aggiornamenti in una cronologia significativa, è necessario usare TOP insieme a ORDER BY in un'istruzione subselect. Nell'esempio seguente le ore di ferie dei 10 dipendenti vengono aggiornate con le prime date di assunzione.

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

Esempi: Azure Synapse Analytics e Piattaforma di strumenti analitici (PDW)

L'esempio seguente restituisce le prime 31 righe corrispondenti ai criteri di query. La clausola ORDER BY garantisce che le 31 righe restituite siano le prime 31 righe in base a un ordinamento alfabetico della colonna LastName.

Uso di TOP senza specificare i legami.

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

Risultato: vengono restituite 31 righe.

Uso di TOP, specificando WITH TIES.

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

Risultato: vengono restituite 33 righe, perché tre dipendenti denominati Brown lega per la prima riga.