RANK e DENSE_RANK in caso di parità
La domanda classica sulla classificazione con o senza salti quando i valori sono pari
RANK e DENSE_RANK in caso di parità è una lezione Coding Interview Prep gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Coding Interview Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Coding Interview Prep include 4 lezioni in totale.
Le tre funzioni di ranking a confronto
SQL offre tre funzioni finestra per il ranking e la domanda sulle finestre più frequente in assoluto riguarda la loro differenza in caso di parità:
- ROW_NUMBER: sempre univoco; ai pari merito assegna numeri distinti arbitrari.
- RANK: i pari merito condividono lo stesso ranking, poi il ranking successivo salta (lasciando un buco).
- DENSE_RANK: i pari merito condividono lo stesso ranking, poi il ranking successivo non salta (non ci sono buchi).
Saper enunciare immediatamente questa distinzione è un indicatore affidabile nei colloqui.
Una tabella con un esempio concreto
Immagini cinque punteggi ordinati in modo decrescente: 100, 90, 90, 80, 70. Osservi come li numera ciascuna funzione.
- ROW_NUMBER: 1, 2, 3, 4, 5
- RANK: 1, 2, 2, 4, 5 (salta 3 dopo la parità)
- DENSE_RANK: 1, 2, 2, 3, 4 (non salta)
Memorizzi questo esempio 100/90/90/80/70: le permetterà di rispondere subito alla domanda.
SELECT
score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS rownum,
RANK() OVER (ORDER BY score DESC) AS rnk,
DENSE_RANK() OVER (ORDER BY score DESC) AS dense
FROM scores;Come RANK calcola il salto
RANK assegna a ogni riga un ranking pari a uno più il numero di righe che la precedono strettamente nell'ordinamento. Le due righe a pari merito con valore 90 sono precedute ciascuna da una riga (la 100), quindi ricevono entrambe il ranking 2. Il valore successivo, più basso, è preceduto da tre righe, quindi passa al ranking 4.
Per questo RANK riproduce il punteggio delle competizioni: medaglie d'argento a pari merito, nessuna medaglia di bronzo.
-- scores 100,90,90,80 -> RANK = 1,2,2,4
SELECT score, RANK() OVER (ORDER BY score DESC) AS rnk
FROM scores;Come DENSE_RANK evita il salto
DENSE_RANK assegna un ranking pari a uno più il numero di valori distinti che precedono il valore corrente. Dopo la parità a 90, davanti a 80 c'erano solo due valori distinti (100 e 90), quindi 80 riceve il ranking 3: non c'è alcun buco.
Usi DENSE_RANK quando contano le posizioni dei valori distinti, ad esempio per trovare "il secondo stipendio più alto" quando i pari merito devono essere conteggiati una sola volta.
-- scores 100,90,90,80 -> DENSE_RANK = 1,2,2,3
SELECT score, DENSE_RANK() OVER (ORDER BY score DESC) AS dense
FROM scores;Quando scegliere ciascuna funzione
Una guida rapida per decidere, che gli intervistatori apprezzano:
- Serve esattamente una riga per posizione (record più recente, paginazione)? → ROW_NUMBER.
- Serve una classifica in cui i pari merito condividano la posizione e i salti siano corretti (classifica sportiva, primi 3 inclusi i pari merito)? → RANK.
- Serve l'N-esimo valore distinto (lo stipendio N-esimo più alto)? → DENSE_RANK.
La scelta sbagliata modifica le righe restituite, quindi motivi la scelta a voce.
Classifica all'interno delle partizioni
Tutte e tre le funzioni accettano PARTITION BY per calcolare la classifica indipendentemente all'interno di ogni gruppo. Ogni partizione riparte dalla posizione 1.
Qui ogni reparto classifica i propri dipendenti in base allo stipendio, gestendo i pari merito con DENSE_RANK. Il dipendente con lo stipendio più alto in ogni reparto occupa la posizione 1 e i dipendenti con lo stesso stipendio condividono la posizione.
SELECT
department,
name,
salary,
DENSE_RANK() OVER (
PARTITION BY department
ORDER BY salary DESC
) AS salary_rank
FROM employees;Esempio svolto: primi 3 inclusi i pari merito
"Restituire i 3 stipendi più alti per reparto e, se più persone sono a pari merito al terzo posto, includerle tutte." Sono necessarie RANK o DENSE_RANK, non ROW_NUMBER.
Usando DENSE_RANK <= 3 si mantengono i primi tre livelli di stipendio distinti e ogni dipendente appartenente a tali livelli: è esattamente questo il significato di "inclusi i pari merito".
SELECT department, name, salary, salary_rank
FROM (
SELECT department, name, salary,
DENSE_RANK() OVER (
PARTITION BY department ORDER BY salary DESC
) AS salary_rank
FROM employees
) t
WHERE salary_rank <= 3;Esempio svolto: il secondo stipendio più alto
La domanda più famosa nei colloqui SQL. La risposta robusta usa DENSE_RANK, così gli stipendi massimi duplicati non fanno perdere di vista il vero secondo valore distinto.
Se tre persone ricevono lo stipendio massimo, DENSE_RANK = 2 identifica comunque correttamente lo stipendio distinto successivo, mentre ROW_NUMBER = 2 restituirebbe semplicemente un altro dipendente con lo stipendio massimo.
SELECT DISTINCT salary AS second_highest
FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS dr
FROM employees
) t
WHERE dr = 2;RANK vs DENSE_RANK per il valore N-esimo più alto
Perché preferire DENSE_RANK a RANK nei problemi sull'N-esimo valore più alto? Perché RANK lascia dei salti. Con gli stipendi 100, 100, 90, il valore 90 ha RANK = 3, ma DENSE_RANK = 2.
Se la domanda chiede il "secondo stipendio distinto più alto", filtrare con RANK = 2 non restituirebbe nulla, mentre DENSE_RANK = 2 restituirebbe correttamente 90. Associare sempre "N-esimo distinto" a DENSE_RANK.
-- salaries 100,100,90
-- RANK: 1,1,3 -> WHERE rank = 2 returns NOTHING
-- DENSE_RANK: 1,1,2 -> WHERE dense_rank = 2 returns 90Note sui dialetti SQL
Buone notizie: ROW_NUMBER, RANK e DENSE_RANK fanno parte dello standard SQL e si comportano allo stesso modo in PostgreSQL, SQL Server, Oracle, MySQL 8+, BigQuery e Snowflake. La gestione dei pari merito descritta sopra è universale.
Una funzione correlata, PERCENT_RANK, si basa su RANK per fornire una posizione relativa compresa tra 0 e 1: vale la pena menzionarla se l'intervistatore chiede informazioni sul ranking percentile.
Errori comuni
Presti attenzione a questi casi:
- Usare
ROW_NUMBERper "l'N-esimo valore più alto" e perdere le righe a pari merito. - Usare
RANKquando la domanda si riferisce a valori distinti, ottenendo poi risultati vuoti a causa dei salti. - Dimenticare
ORDER BYall'interno diOVER: senza di esso la classifica non ha significato. - Filtrare la classifica direttamente in
WHEREinvece che in una query esterna.
Verifica rapida
Applichi le regole sui pari merito.
Riepilogo: con salti e senza salti
Ora può scegliere immediatamente la funzione di ranking corretta:
- ROW_NUMBER: numeri univoci, senza posizioni condivise.
- RANK: i pari merito condividono la posizione, poi si crea un salto (1,2,2,4).
- DENSE_RANK: i pari merito condividono la posizione, senza salti (1,2,2,3).
- "N-esimo valore distinto più alto" →
DENSE_RANK; "primi N inclusi i pari merito" →RANK/DENSE_RANK; "una riga per posizione" →ROW_NUMBER.
Prossimo argomento: come filtrare effettivamente il risultato di una funzione finestra, dato che non è possibile farlo in WHERE.
Domande Frequenti
La lezione «RANK e DENSE_RANK in caso di parità» è gratuita?
Sì — il testo completo di «RANK e DENSE_RANK in caso di parità» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Coding Interview Prep, passa a CoddyKit PRO. Il corso Coding Interview Prep include 4 lezioni in totale.
Cosa imparerò in «RANK e DENSE_RANK in caso di parità»?
La domanda classica sulla classificazione con o senza salti quando i valori sono pari Eserciti Coding Interview Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Coding Interview Prep?
Non è richiesta alcuna esperienza precedente. Coding Interview Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «RANK e DENSE_RANK in caso di parità»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Coding Interview Prep?
Sì. Ogni lezione Coding Interview Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- OVER, PARTITION BY e ORDER BY
- ROW_NUMBER per una sequenza univoca
- RANK e DENSE_RANK in caso di parità
- Filtrare un risultato di finestra