Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Fonctions de classement dans SQL Server

Supposons que vous conceviez une application de base de données SQL Server pour le PDG d'une entreprise et que vous deviez afficher le cinquième employé le mieux payé de l'entreprise.

Que feriez-vous? Une solution consiste à écrire une requête comme celle-ci :

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

La requête ci-dessus semble fastidieuse, en particulier si vous devez classer tous les employés. Dans ce cas, une solution consiste à lister les salariés par ordre décroissant de salaire puis à prendre l'indice du salarié comme rang. Cependant, les choses se compliquent si plusieurs employés ont le même salaire. Comment les classeriez-vous ?

Heureusement, SQL Server est livré avec des fonctions de classement intégrées qui peuvent être utilisées pour classer les enregistrements de différentes manières. Dans cet article, nous présenterons en détail les fonctions de classement des serveurs SQL en les illustrant avec des exemples.

Il existe quatre types différents de fonction de classement dans SQL Server :

  • Rang()
  • Dense_Rank()
  • Numéro de ligne()
  • Ntile()

Il est important de mentionner que toutes les fonctions de classement dans SQL Server nécessitent la clause ORDER BY.

Avant d'examiner en détail chacune des fonctions de classement, créons d'abord des données factices que nous utiliserons dans cet article pour expliquer la fonction de classement. Exécutez le script suivant :

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

Dans le script ci-dessus, nous créons une base de données Showroom avec une table Car. La table Car comporte cinq attributs :CarId, Name, Make, Model, Price et Type.

Ensuite, nous avons ajouté 12 enregistrements factices dans la table Car.

Maintenant, vous voyez chacune des fonctions de classement.

1. Fonction de classement

La fonction de classement dans SQL Server attribue un classement à chaque enregistrement classé par la clause ORDER BY. Par exemple, si vous souhaitez voir la cinquième voiture la plus chère dans le tableau des voitures, vous pouvez utiliser la fonction de classement comme suit :

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

Dans le script ci-dessus, sélectionnez le nom, la marque, le modèle, le prix, le type et le rang de chaque voiture commandée par prix dans la colonne "PriceRank". La syntaxe de la fonction Rank est simple. Vous devez écrire la fonction RANK suivie de l'opérateur OVER. À l'intérieur de l'opérateur OVER, vous devez passer la clause ORDER BY qui trie les données. La sortie du script ci-dessus ressemble à ceci :

Vous pouvez voir le rang de chaque voiture. Il est important de mentionner que s'il y a égalité entre les rangs de deux records, la position de classement suivante est ignorée. Par exemple, il existe un lien entre les enregistrements 5 et 6 dans la sortie. Parado et Civic ont des prix égaux et ont donc été classés 5. Cependant, le rang suivant, en particulier le rang 6, est ignoré et les deux voitures suivantes de la liste ont été classées 7 car elles ont également le même prix. Après le 7e rang, le rang 8 est à nouveau sauté et le prochain rang attribué est le 9.

Vous pouvez diviser les données en partitions, puis appliquer un classement aux partitions individuelles. Dans le script suivant, il y a la partition des enregistrements par type. Nous classons les voitures à l'intérieur de chaque partition.

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

La sortie du script ci-dessus ressemble à ceci :

Il ressort clairement de la sortie que les enregistrements ont été partitionnés en fonction des types de voitures et que le rang a été attribué localement à l'intérieur de la partition. Par exemple, les deux premiers enregistrements appartiennent à la partition "Hatchback" et ont été classés 1 et 2. Pour la partition suivante, c'est-à-dire "Sedan", le rang est réinitialisé à 1.

2. Fonction Dense_Rank

La fonction dense_rank est similaire à la fonction rank. Cependant, dans le cas de dense_rank, s'il existe une égalité entre deux enregistrements en termes de rang, le rang suivant n'est pas ignoré. Voyons le démontrer avec l'exemple. Exécutez le script suivant :

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

Encore une fois, vous pouvez voir que les 5e et 6e enregistrements ont la même valeur pour Price et que les deux ont reçu le rang 5. Cependant, contrairement à la fonction de rang qui a sauté le rang suivant, la fonction dense_rank ne saute pas le rang suivant, et le rang 6 a été affecté à l'enregistrement suivant.

Comme la fonction de classement, la fonction dense_rank peut également être appliquée à la partition par clause. Regardez le script suivant :

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

La sortie du script ci-dessus ressemble à ceci :

3. Fonction Row_Number

La fonction row_number classe également les enregistrements en fonction des conditions spécifiées par la clause ORDER BY. Cependant, contrairement aux fonctions rank et dense_rank, la fonction row_number n'attribue pas le même rang lorsqu'il existe des valeurs en double pour la colonne spécifiée par la clause ORDER BY. Regardez le script suivant :

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

La sortie du script ci-dessus ressemble à ceci :

Dans le script ci-dessus, vous pouvez voir que les 5e et 6e enregistrements ont la même valeur pour la colonne Prix, mais le rang qui leur est attribué est différent.

De même, la fonction row_number peut être appliquée aux données partitionnées. Regardez le script suivant par exemple.

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

La sortie du script ci-dessus ressemble à ceci :

4. Fonction NTILE

La fonction NTILE regroupe le classement. Supposons que vous ayez 12 enregistrements dans une table et que vous souhaitiez les classer en groupes de 4. Les trois premiers enregistrements auront le rang 1, les trois enregistrements suivants auront le rang 2 et ainsi de suite.

Examinons un exemple de la fonction NTILE.

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

Dans le script ci-dessus, nous avons passé 4 comme paramètre à la fonction NTILE. Puisque nous avons 12 enregistrements, vous verrez un total de 4 rangs différents où 1 rang sera attribué à trois enregistrements. La sortie ressemble à ceci :

Vous pouvez voir que les trois premières voitures les plus chères ont été classées 1, les trois suivantes ont été classées 2 et ainsi de suite.

La fonction NTILE peut également être appliquée aux données partitionnées. Regardez le script suivant :

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

Conclusion

Les fonctions de classement dans SQL Server sont utilisées pour classer les données de différentes manières. Dans cette lecture, nous avons introduit différents types de fonctions de classement avec les exemples. Les fonctions rank et dense_rank donnent le même rang aux données avec les mêmes valeurs dans la clause ORDER BY tandis que la fonction row_number classe l'enregistrement de manière incrémentielle même s'il y a une égalité.
En cas d'absence d'enregistrements en double dans la colonne spécifiée par la clause ORDER BY, les fonctions rank, dense_rank et row_number se comportent de manière similaire.