Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Classificazione delle funzioni in SQL Server

Si supponga di progettare un'applicazione di database SQL Server per il CEO di un'azienda e di dover visualizzare il quinto dipendente più pagato dell'azienda.

Cosa faresti? Una soluzione è scrivere una query come questa:

SELECT EmployeeName
FROM Employees
ORDER BY Salary DESC
OFFSET 4 ROWS
FETCH FIRST 1 ROWS ONLY;

La query sopra sembra ingombrante, in particolare se devi classificare tutti i dipendenti. In tal caso, una soluzione è elencare i dipendenti in ordine decrescente di stipendio e quindi prendere l'indice del dipendente come grado. Tuttavia, le cose si complicano se più dipendenti hanno lo stesso stipendio. Come li classificheresti?

Fortunatamente, SQL Server include funzioni di classificazione integrate che possono essere utilizzate per classificare i record in vari modi. In questo articolo, introdurremo in dettaglio le funzioni di classificazione dei server SQL, illustrandole con gli esempi.

Esistono quattro diversi tipi di funzioni di classificazione in SQL Server:

  • Classifica()
  • Rango_denso()
  • Numero riga()
  • Ntile()

È importante ricordare che tutte le funzioni di classificazione in SQL Server richiedono la clausola ORDER BY.

Prima di esaminare in dettaglio ciascuna delle funzioni di classificazione, creiamo innanzitutto dati fittizi che utilizzeremo in questo articolo per spiegare la funzione di classificazione. Esegui il seguente script:

CREATE DATABASE Showroom

Use Showroom
CREATE TABLE Car
(
CarId int identity(1,1) primary key,
Name varchar(100),
Make varchar(100),
Model int ,
Price int ,
Type varchar(20)
)

insert into Car( Name, Make, Model , Price, Type)
VALUES ('Corrolla','Toyota',2015, 20000,'Sedan'),
('Civic','Honda',2018, 25000,'Sedan'),
('Passo','Toyota',2012, 18000,'Hatchback'),
('Land Cruiser','Toyota',2017, 40000,'SUV'),
('Corrolla','Toyota',2011, 17000,'Sedan'),
('Vitz','Toyota',2014, 15000,'Hatchback'),
('Accord','Honda',2018, 28000,'Sedan'),
('7500','BMW',2015, 50000,'Sedan'),
('Parado','Toyota',2011, 25000,'SUV'),
('C200','Mercedez',2010, 26000,'Sedan'),
('Corrolla','Toyota',2014, 19000,'Sedan'),
('Civic','Honda',2015, 20000,'Sedan')

Nello script sopra, creiamo il database Showroom con una tabella Car. La tabella Car ha cinque attributi:CarId, Nome, Marca, Modello, Prezzo e Tipo.

Successivamente, abbiamo aggiunto 12 record fittizi nella tabella Auto.

Ora puoi vedere ciascuna delle funzioni di classifica.

1. Funzione di grado

La funzione di classificazione in SQL Server assegna la classificazione a ogni record ordinato dalla clausola ORDER BY. Ad esempio, se vuoi vedere la quinta auto più costosa nella tabella Auto, puoi utilizzare la funzione classifica come segue:

Use Showroom
SELECT Name,Make,Model, Price, Type,
RANK() OVER(ORDER BY Price DESC) as PriceRank
FROM Car

Nello script sopra, seleziona Nome, Marca, Modello, Prezzo, Tipo e la classifica di ogni auto ordinata per Prezzo come colonna "PriceRank". La sintassi per la funzione Rank è semplice. Devi scrivere la funzione RANK seguita dall'operatore OVER. All'interno dell'operatore OVER, devi passare la clausola ORDER BY che ordina i dati. L'output dello script sopra è simile al seguente:

Puoi vedere la classifica per ogni macchina. È importante ricordare che se c'è un pareggio tra i ranghi di due record, la posizione in classifica successiva viene saltata. Ad esempio, c'è un pareggio tra il record 5 e 6 nell'output. Sia Parado che Civic hanno prezzi uguali e quindi sono stati classificati 5. Tuttavia, il grado successivo, in particolare il grado 6, viene saltato e le due auto successive nell'elenco sono state classificate 7 poiché anche loro hanno lo stesso prezzo. Dopo il settimo grado, il grado 8 viene nuovamente saltato e il grado successivo assegnato è 9.

È possibile dividere i dati in partizioni e quindi applicare la classificazione alle singole partizioni. Nello script seguente c'è la partizione dei record per tipo. Classifichiamo le auto all'interno di ogni partizione.

SELECT Name,Make,Model, Price, Type,
RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as PriceRank
FROM Car

L'output dello script sopra è simile al seguente:

È evidente dall'output che i record sono stati partizionati in base ai tipi di auto e il rango è stato assegnato localmente all'interno della partizione. Ad esempio, i primi due record appartengono alla partizione "Hatchback" e sono stati classificati 1 e 2. Per la partizione successiva, ovvero "Sedan", il grado viene reimpostato su 1.

2. Funzione Dense_Rank

La funzione dense_rank è simile alla funzione rank. Tuttavia, in caso di dense_rank, se c'è un pareggio tra due record in termini di rango, il rango successivo non viene saltato. Vediamo dimostrarlo con l'esempio. Esegui il seguente script:

Use Showroom
SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(ORDER BY Price DESC) as DensePriceRank
FROM Car

Ancora una volta puoi vedere che il 5° e il 6° record hanno lo stesso valore per Prezzo e ad entrambi è stato assegnato il rango 5. Tuttavia, a differenza della funzione rank che ha saltato il rank successivo, la funzione dense_rank non salta il rank successivo e il rank 6 è stato assegnato al record successivo.

Come la funzione rank, anche la funzione dense_rank può essere applicata alla partizione per clausola. Guarda il seguente script:

SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank
FROM Car

L'output dello script sopra è simile al seguente:

3. Funzione numero_riga

La funzione row_number classifica anche i record in base alle condizioni specificate dalla clausola ORDER BY. Tuttavia, a differenza delle funzioni rank e dense_rank, la funzione row_number non assegna lo stesso rank dove sono presenti valori duplicati per la colonna specificata dalla clausola ORDER BY. Guarda il seguente script:

SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank
FROM Car

L'output dello script sopra è simile al seguente:

Dallo script sopra, puoi vedere che sia il 5° che il 6° record hanno lo stesso valore per la colonna Prezzo, ma il rango assegnato loro è diverso.

Allo stesso modo, la funzione row_number può essere applicata ai dati partizionati. Guarda ad esempio il seguente script.

SELECT Name,Make,Model, Price, Type,
ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Price DESC) AS PriceRankRow
FROM Car

L'output dello script sopra è simile al seguente:

4. Funzione NILE

La funzione NTILE raggruppa la classifica. Supponiamo di avere 12 record in una tabella e di volerli classificare in gruppi di 4. I primi tre record avranno il rango 1, i tre record successivi avranno il rango 2 e così via.

Diamo un'occhiata a un esempio della funzione NTILE.

Use Showroom
SELECT Name,Make,Model, Price, Type,
NTILE(4) OVER(ORDER BY Price DESC) as NtilePrice
FROM Car

Nello script precedente, abbiamo passato 4 come parametro alla funzione NTILE. Poiché abbiamo 12 record, vedrai un totale di 4 diversi gradi in cui 1 grado verrà assegnato a tre record. L'output è simile a questo:

Puoi vedere che le prime tre auto più costose sono state classificate 1, le successive tre sono state classificate 2 e così via.

La funzione NTILE può essere applicata anche ai dati partizionati. Guarda il seguente script:

SELECT Name,Make,Model, Price, Type,
NTILE(4) OVER(PARTITION BY Type ORDER BY Price DESC) as NtilePrice
FROM Car

Conclusione

Le funzioni di classificazione in SQL Server vengono utilizzate per classificare i dati in modi diversi. In questa lettura, abbiamo introdotto diversi tipi di funzioni di classificazione con gli esempi. Le funzioni rank e dense_rank danno lo stesso rango ai dati con gli stessi valori nella clausola ORDER BY mentre la funzione row_number classifica il record in modo incrementale anche se c'è un pareggio.
In caso di record non duplicati nella colonna specificata dalla clausola ORDER BY, le funzioni rank, dense_rank e row_number si comportano in modo simile.