DENSE_RANK (Transact-SQL)

Si applica a:SQL ServerDatabase SQL di AzureIstanza gestita di SQL di AzureAzure Synapse AnalyticsPiattaforma di analisi (PDW)Endpoint di analisi SQL in Microsoft FabricMagazzino in Microsoft FabricDatabase SQL in Microsoft Fabric

Questa funzione restituisce il rango di ogni riga all'interno della partizione di un set di risultati, senza gap nei valori di rango. Il rango di una riga specifica corrisponde a 1 più il numero di valori di rango distinti che precedono tale riga specifica.

Convenzioni relative alla sintassi Transact-SQL

Sintassi

DENSE_RANK ( ) OVER ( [ <partition_by_clause> ] < order_by_clause > )  

Argomenti

<partition_by_clause>

Prima suddivide il set di risultati generato dalla clausola FROM in partizioni e quindi la funzione DENSE_RANK viene applicata a ogni partizione. Vedere Clausola OVER (Transact-SQL) per la sintassi di PARTITION BY.

<order_by_clause>

Determina l'ordine in cui la funzione DENSE_RANK viene applicata alle righe in una partizione.

Tipi restituiti

bigint

Osservazioni:

Se due o più righe hanno lo stesso valore di rango nella stessa partizione, ciascuna di queste righe riceve lo stesso rango. Ad esempio, se i due migliori venditori hanno lo stesso SalesYTD valore, entrambi hanno un valore di rango di uno. Il venditore con il secondo valore di grado più SalesYTD alto ha un valore di rango di due. Questo valore di rango supera di uno il numero di righe distinte che precedono la riga in questione. Pertanto, i numeri restituiti dalla DENSE_RANK funzione non presentano lacune e hanno sempre valori di rango consecutivi.

L'ordinamento usato per l'intera query determina l'ordine delle righe nel set di risultati. Questo ordine implica che una riga classificata come numero uno non deve necessariamente essere la prima fila della partizione.

DENSE_RANK è non deterministico. Per altre informazioni, vedere Funzioni deterministiche e non deterministiche.

Per le indicazioni sulla regolazione delle prestazioni delle funzioni della finestra, vedi considerazioni sulle prestazioni OVER().

Esempi

R. Righe di rango all'interno di una partizione

Questo esempio assegna i ranghi per i prodotti nell'inventario, in base alle ubicazioni di inventario specificate, a seconda delle quantità. DENSE_RANK partiziona il set di risultati per LocationID e ordina in modo logico il set di risultati per Quantity. I prodotti 494 e 495 hanno la stessa quantità. Poiché hanno entrambi lo stesso valore relativo alla quantità, hanno entrambi il valore di rango 1.

USE AdventureWorks2022;  
GO  
SELECT i.ProductID, p.Name, i.LocationID, i.Quantity  
    ,DENSE_RANK() OVER   
    (PARTITION BY i.LocationID ORDER BY i.Quantity DESC) AS Rank  
FROM Production.ProductInventory AS i   
INNER JOIN Production.Product AS p   
    ON i.ProductID = p.ProductID  
WHERE i.LocationID BETWEEN 3 AND 4  
ORDER BY i.LocationID;  
GO  

Il set di risultati è il seguente.

ProductID   Name                               LocationID Quantity Rank  
----------- ---------------------------------- ---------- -------- -----  
494         Paint - Silver                     3          49       1  
495         Paint - Blue                       3          49       1  
493         Paint - Red                        3          41       2  
496         Paint - Yellow                     3          30       3  
492         Paint - Black                      3          17       4  
495         Paint - Blue                       4          35       1  
496         Paint - Yellow                     4          25       2  
493         Paint - Red                        4          24       3  
492         Paint - Black                      4          14       4  
494         Paint - Silver                     4          12       5  

(10 row(s) affected)  

B. Classifica tutte le righe di un set di risultati

Questo esempio restituisce i primi dieci dipendenti classificati in base allo stipendio. Poiché l'istruzione SELECT non specifica una PARTITION BY clausola, la DENSE_RANK funzione si applica a tutte le righe dell'insieme dei risultati.

USE AdventureWorks2022;  
GO  
SELECT TOP(10) BusinessEntityID, Rate,   
       DENSE_RANK() OVER (ORDER BY Rate DESC) AS RankBySalary  
FROM HumanResources.EmployeePayHistory;  

Il set di risultati è il seguente.

BusinessEntityID Rate                  RankBySalary  
---------------- --------------------- --------------------  
1                125.50                1  
25               84.1346               2  
273              72.1154               3  
2                63.4615               4  
234              60.0962               5  
263              50.4808               6  
7                50.4808               6  
234              48.5577               7  
285              48.101                8  
274              48.101                8  

C. Quattro funzioni di rango usate nella stessa query

Questo esempio illustra le quattro funzioni di rango

usate nella stessa query. Per esempi specifici, vedere l'argomento relativo a ogni funzione di rango.

USE AdventureWorks2022;  
GO  
SELECT p.FirstName, p.LastName  
    ,ROW_NUMBER() OVER (ORDER BY a.PostalCode) AS "Row Number"  
    ,RANK() OVER (ORDER BY a.PostalCode) AS Rank  
    ,DENSE_RANK() OVER (ORDER BY a.PostalCode) AS "Dense Rank"  
    ,NTILE(4) OVER (ORDER BY a.PostalCode) AS Quartile  
    ,s.SalesYTD  
    ,a.PostalCode  
FROM Sales.SalesPerson AS s   
    INNER JOIN Person.Person AS p   
        ON s.BusinessEntityID = p.BusinessEntityID  
    INNER JOIN Person.Address AS a   
        ON a.AddressID = p.BusinessEntityID  
WHERE TerritoryID IS NOT NULL AND SalesYTD <> 0;  

Il set di risultati è il seguente.

FirstName LastName Numero di riga Classifica Grado Denso Quartile SalesYTD PostalCode
Michael Blythe 1 1 1 1 4557045.0459 98027
Linda Mitchell 2 1 1 1 5200475.2313 98027
Jillian Carson 3 1 1 1 3857163.6332 98027
Garrett Vargas 4 1 1 1 1764938.9859 98027
Tsvi Reiter 5 1 1 2 2811012.7151 98027
Shu Ito 6 6 2 2 3018725.4858 98055
José Saraiva 7 6 2 2 3189356.2465 98055
David Campbell 8 6 2 3 3587378.4257 98055
Tete Mensa-Annan 9 6 2 3 1931620.1835 98055
Lynn Tsoflias 10 6 2 3 1758385.926 98055
Rachel Valdez 11 6 2 4 2241204.0424 98055
Jae Pak 12 6 2 4 5015682.3752 98055
Ranjit Varkey Chudukatil 13 6 2 4 3827950.238 98055

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

D: Classificazione di righe all'interno di una partizione

Questo esempio classifica gli addetti alle vendite in ogni territorio di vendita in base al totale delle vendite. DENSE_RANK partiziona il set di righe per SalesTerritoryGroup e ordina il set di risultati per SalesAmountQuota.

-- Uses AdventureWorks  

SELECT LastName, SUM(SalesAmountQuota) AS TotalSales, SalesTerritoryGroup,  
    DENSE_RANK() OVER (PARTITION BY SalesTerritoryGroup ORDER BY SUM(SalesAmountQuota) DESC ) AS RankResult  
FROM dbo.DimEmployee AS e  
INNER JOIN dbo.FactSalesQuota AS sq ON e.EmployeeKey = sq.EmployeeKey  
INNER JOIN dbo.DimSalesTerritory AS st ON e.SalesTerritoryKey = st.SalesTerritoryKey  
WHERE SalesPersonFlag = 1 AND SalesTerritoryGroup != N'NA'  
GROUP BY LastName, SalesTerritoryGroup;  

Il set di risultati è il seguente.

 LastName          TotalSales     SalesTerritoryGroup  RankResult  
----------------  -------------  -------------------  --------  
Pak               10514000.0000  Europe               1  
Varkey Chudukatil  5557000.0000  Europe               2  
Valdez             2287000.0000  Europe               3  
Carson            12198000.0000  North America        1  
Mitchell          11786000.0000  North America        2  
Blythe            11162000.0000  North America        3  
Reiter             8541000.0000  North America        4  
Ito                7804000.0000  North America        5  
Saraiva            7098000.0000  North America        6  
Vargas             4365000.0000  North America        7  
Campbell           4025000.0000  North America        8  
Ansman-Wolfe       3551000.0000  North America        9  
Mensa-Annan        2753000.0000  North America        10  
Tsoflias           1687000.0000  Pacific              1