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

Quand et comment utiliser la clause SQL PARTITION BY

Dans cet article, nous allons explorer quand et comment utiliser la clause SQL PARTITION BY et la comparer à l'utilisation de la clause GROUP BY.

Comprendre la fonction Fenêtre

Les utilisateurs de la base de données utilisent des fonctions d'agrégation telles que MAX(), MIN(), AVERAGE() et COUNT() pour effectuer l'analyse des données. Ces fonctions opèrent sur une table entière et renvoient des données agrégées uniques à l'aide de la clause GROUP BY. Parfois, nous avons besoin de valeurs agrégées sur un petit ensemble de lignes. Dans ce cas, la fonction Window combinée à la fonction d'agrégation permet d'obtenir la sortie souhaitée. La fonction Window utilise la clause OVER() et peut inclure les fonctions suivantes :

  • Partitionner par :  Cela divise les lignes ou le jeu de résultats de la requête en petites partitions.
  • Trier par :  Cela organise les lignes dans l'ordre croissant ou décroissant pour la fenêtre de partition. L'ordre par défaut est croissant.
  • Ligne ou plage :  Vous pouvez limiter davantage les lignes d'une partition en spécifiant les points de début et de fin.

Dans cet article, nous nous concentrerons sur l'exploration de la clause SQL PARTITION BY.

Préparation des exemples de données

Supposons que nous ayons une table [SalesLT].[Orders] qui stocke les détails des commandes des clients. Il a une colonne [Ville] qui spécifie la ville du client où la commande a été passée.

CREATE TABLE [SalesLT].[Orders]
(
orderid INT,
orderdate DATE,
customerName VARCHAR(100),
City VARCHAR(50),
amount MONEY
)
INSERT INTO [SalesLT].[Orders]
SELECT 1,'01/01/2021','Mohan Gupta','Alwar',10000
UNION ALL
SELECT 2,'02/04/2021','Lucky Ali','Kota',20000
UNION ALL
SELECT 3,'03/02/2021','Raj Kumar','Jaipur',5000
UNION ALL
SELECT 4,'04/02/2021','Jyoti Kumari','Jaipur',15000
UNION ALL
SELECT 5,'05/03/2021','Rahul Gupta','Jaipur',7000
UNION ALL
SELECT 6,'06/04/2021','Mohan Kumar','Alwar',25000
UNION ALL
SELECT 7,'07/02/2021','Kashish Agarwal','Alwar',15000
UNION ALL
SELECT 8,'08/03/2021','Nagar Singh','Kota',2000
UNION ALL
SELECT 9,'09/04/2021','Anil KG','Alwar',1000
Go

Disons que nous voulons connaître la valeur totale des commandes par emplacement (ville). À cette fin, nous utilisons les fonctions SUM() et GROUP BY comme indiqué ci-dessous.

SELECT City AS CustomerCity
,sum(amount) AS totalamount FROM [SalesLT].[Orders]
GROUP BY city
ORDER BY city

Dans l'ensemble de résultats, nous ne pouvons pas utiliser les colonnes non agrégées dans l'instruction SELECT. Par exemple, nous ne pouvons pas afficher [CustomerName] dans la sortie car il n'est pas inclus dans la clause GROUP BY.

SQL Server donne le message d'erreur suivant si vous essayez d'utiliser la colonne non agrégée dans la liste des colonnes.

SELECT City AS CustomerCity, CustomerName,amount,
SUM(amount) OVER(PARTITION BY city) TotalOrderAmount
FROM [SalesLT].[Orders]

Comme indiqué ci-dessous, la clause PARTITION BY crée une fenêtre plus petite (ensemble de lignes de données), effectue l'agrégation et l'affiche. Vous pouvez également afficher des colonnes non agrégées dans cette sortie.

De même, vous pouvez utiliser les fonctions AVG(), MIN(), MAX() pour calculer le montant moyen, minimum et maximum à partir des lignes d'une fenêtre.

SELECT City AS CustomerCity, CustomerName,amount,
SUM(amount) OVER(PARTITION BY city) TotalOrderAmount,
Avg(amount) OVER(PARTITION BY city) AvgOrderAmount,
Min(amount) OVER(PARTITION BY city) MinOrderAmount,
MAX(amount) OVER(PARTITION BY city) MaxOrderAmount
FROM [SalesLT].[Orders]

Utilisation de la clause SQL PARTITION BY avec la fonction ROW_NUMBER()

Auparavant, nous obtenions les valeurs agrégées dans une fenêtre à l'aide de la clause PARTITION BY. Supposons qu'au lieu du total, nous ayons besoin du total cumulé dans une partition.

Un total cumulé fonctionne de la manière suivante.

Ligne Total cumulé
1 Rang 1+ 2
2 Rang 2+3
3 Rang 3+4

Le rang de ligne est calculé à l'aide de la fonction ROW_NUMBER(). Commençons par utiliser cette fonction et visualisons les rangs des lignes.

  • La fonction ROW_NUMBER() utilise les clauses OVER et PARTITION BY et trie les résultats par ordre croissant ou décroissant. Il commence à classer les lignes à partir de 1 selon l'ordre de tri.
SELECT City AS CustomerCity, CustomerName,amount,
ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number]
FROM [SalesLT].[Orders]

Par exemple, dans la ville [Alwar], la ligne avec le montant le plus élevé (25 000,00) se trouve dans la ligne 1. Comme indiqué ci-dessous, elle classe les lignes dans la fenêtre spécifiée par la clause PARTITION BY. Par exemple, nous avons trois villes différentes [Alwar], [Jaipur] et [Kota], et chaque fenêtre (ville) obtient son rang de ligne.

Pour calculer le total cumulé, nous utilisons les arguments suivants.

  • CURRENT ROW :Il spécifie le point de départ et de fin dans la plage spécifiée.
  • 1 suivant :Il spécifie le nombre de lignes (1) à suivre à partir de la ligne actuelle.
SELECT City AS CustomerCity, CustomerName,amount,
ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number],
SUM(amount) OVER(PARTITION BY city ORDER BY amount DESC ROWS BETWEEN
CURRENT ROW AND 1 FOLLOWING) AS CumulativeSUM
FROM [SalesLT].[Orders]

L'image suivante montre que vous obtenez un total cumulé au lieu d'un total global dans une fenêtre spécifiée par la clause PARTITION BY.

Si nous utilisons ROWS UNBOUNDED PRECEDING  dans la clause SQL PARTITION BY, il calcule le total cumulé de la manière suivante. Il utilise les lignes actuelles avec les lignes ayant les valeurs les plus élevées dans la fenêtre spécifiée.

Ligne Total cumulé
1 Rang 1
2 Rang 1+2
3 Rang 1+2+3
SELECT City AS CustomerCity, CustomerName,amount,
ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number],
SUM(amount) OVER(PARTITION BY city ORDER BY amount DESC
ROWS UNBOUNDED PRECEDING) AS CumulativeSUM
FROM [SalesLT].[Orders]

Comparaison des clauses GROUP BY et SQL PARTITION BY

GROUPER PAR PARTITION PAR
Il renvoie une ligne par groupe après avoir calculé les valeurs agrégées. Il renvoie toutes les lignes de l'instruction SELECT avec des colonnes supplémentaires de valeurs agrégées.
Nous ne pouvons pas utiliser la colonne non agrégée dans l'instruction SELECT. Nous pouvons utiliser les colonnes requises dans l'instruction SELECT, et cela ne produit aucune erreur pour la colonne non agrégée.
Il faut utiliser la clause HAVING pour filtrer les enregistrements de l'instruction SELECT. La fonction PARTITION peut avoir des prédicats supplémentaires dans la clause WHERE en plus des colonnes utilisées dans l'instruction SELECT.
GROUP BY est utilisé dans les agrégats réguliers. PARTITION BY est utilisé dans les agrégats fenêtrés.
Nous ne pouvons pas l'utiliser pour calculer les numéros de lignes ou leurs rangs. Il peut calculer les numéros de lignes et leurs rangs dans la petite fenêtre.

Le mettre à profit

Il est recommandé d'utiliser la clause SQL PARTITION BY lorsque vous travaillez avec plusieurs groupes de données pour les valeurs agrégées dans le groupe individuel. De même, il peut être utilisé pour afficher les lignes d'origine avec la colonne supplémentaire de valeurs agrégées.