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
, MERGE
o 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.
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 clausoleTOP
oFETCH
durante l'ottimizzazione della query. Poiché si usaSET 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
, MERGE
e 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
, MERGE
o 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
, EXCEPT
o 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
, MERGE
o 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
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.