10. Opération de Groupe
Dans l'analyse de données, il est souvent nécessaire de regrouper des informations pour en extraire des tendances ou des indicateurs synthétiques. C'est ici que les clauses GROUP BY et HAVING entrent en jeu.
GROUP BY
La clause GROUP BY est utilisée pour regrouper les résultats d'une requête en fonction des valeurs d'une ou plusieurs colonnes. Elle permet de créer des groupes distincts basés sur les valeurs des colonnes spécifiées. Ensuite, des fonctions d'agrégation, telles que COUNT( ), SUM( ), AVG( ), MAX( ), MIN( ) peuvent être appliquées à chaque groupe pour effectuer des calculs sur les données au sein de chaque groupe.
Ci-dessous, imaginons la table personnel avec les colonnes suivantes : identifiant, nom, salaire et service.
| id | nom | salaire | service |
|---|---|---|---|
| 1 | Alice | 50000 | Ventes |
| 2 | Bob | 48000 | Ventes |
| 3 | Carol | 55000 | Ventes |
| 4 | David | 70000 | RH |
| 5 | Emma | 55000 | RH |
| 6 | Frank | 58000 | RH |
A présent, nous souhaitons connaître le salaire moyen par service afin d'obtenir le résultat suivant :
| service | salaireAvg |
|---|---|
| Ventes | 51000 |
| RH | 61000 |
La requête pour obtenir ce résultat sera :
SELECT service, AVG(salaire)
FROM personnel
GROUP BY service ;où la colonne service est spécifiée dans la clause GROUP BY pour créer des groupes et AVG(salaire) correspond à la fonction d'agrégation appliquée pour obtenir le salaire moyen.
Une manière de généraliser la syntaxe ci-dessus est d'écrire :
SELECT column1, column2, aggregate_function(column3)
FROM table1
GROUP BY column1, column2 ;column1, column2 : Colonnes spécifiées pour créer des groupes distincts.
aggregate_function(column3) : Fonction d'agrégation appliquée à chaque groupe.
La clause GROUP BY sera employée pour obtenir des statistiques par groupe. Dans la requête ci-dessous, l'objectif est de déterminer les 5 principaux clients ayant effectué le plus dépense. Elle effectue la somme de toutes les commandes par client, puis ordonne le résultat.
/* Afficher le top 5 des clients ayant le plus acheté (en terme de dépense) */
SELECT customerKey, ROUND(SUM(UnitPrice*OrderQuantity*(1-UnitPriceDiscountPct)),0) as salesAmount
FROM factInternetSale
GROUP BY customerKey
ORDER BY salesAmount DESC
LIMIT 5 ;Question 10.1
Dans la table factInternetSale, affiche le nombre de commandes réalisées par clients. Pour accéder à la console SQL.
Question 10.2
Dans la table factInternetSale, affiche les 10 clients ayant réalisés le plus de commandes. Pour accéder à la console SQL.
La clause GROUP BY peut également être utilisée pour grouper plusieurs colonnes. À présent, les dépenses sont groupées par clients et par années
SELECT customerKey,YEAR(OrderDate) as orderYear, ROUND(SUM(UnitPrice*OrderQuantity*(1-UnitPriceDiscountPct)),0) as salesAmount
FROM factInternetSale
GROUP BY customerKey,YEAR(OrderDate)
ORDER BY YEAR(OrderDate), salesAmount DESC ;En résumé, la clause GROUP BY utilisée avec des fonctions d'agrégation permet de convertir les données en informations descriptives. Toutefois, il peut être nécessaire, par moments, de filtrer les résultats agrégés en fonction de conditions spécifiques, c'est précisément à ce stade que la clause HAVING intervient.
HAVING
La clause HAVING , associée à la clause GROUP BY, sert à effectuer des filtres comme la clause WHERE. Toutefois, la différence réside dans le fait que la clause HAVING effectue des filtres sur des lignes agrégées (à partir des fonctions d'agrégations vu dans la section GROUP BY) alors que la clause WHERE les effectue au niveau des lignes individuelles.
/* Affiche les clients qui ont effectué au moins 10 commandes sur une année */
SELECT customerKey,YEAR(OrderDate) as orderYear, COUNT(salesOrderNumber) as nOrder
FROM factInternetSale
WHERE nOrder > 9
ORDER BY nOrder DESC, customerKey,YEAR(OrderDate) ;La requête ci-dessus ne fonctionne pas.
La clause WHERE ne peut pas évaluer des conditions sur des opérations de groupe. Elle ne fonctionne que sur les lignes individuelles. À la place il faudra utiliser HAVING.
SELECT customerKey,YEAR(OrderDate) as orderYear, COUNT(salesOrderNumber) as nOrder
FROM factInternetSale
GROUP BY customerKey,YEAR(OrderDate)
HAVING nOrder > 9
ORDER BY nOrder DESC, customerKey,YEAR(OrderDate) ;A présent, la requête fonctionne, la clause HAVING fonctionne très bien avec les fonctions d'agrégation.
En conclusion, la clause HAVING est utilisée pour filtrer les résultats agrégés après l'application de la clause GROUP BY. Elle permet d'appliquer des conditions spécifiques aux groupes créés par GROUP BY, en se basant sur les résultats agrégés des fonctions telles que COUNT( ), SUM( ), AVG( ), MAX( ), MIN( ).
La principale différence avec la clause WHERE réside dans le moment où elles sont appliquées :
- WHERE : Filtrage des lignes individuelles avant le regroupement, agissant sur les données brutes.
- HAVING : Filtrage des groupes résultants après le regroupement, agissant sur les résultats agrégés.
Question 10.3
Dans la table factInternetSale, affiche tous les clients ayant commandé pour plus de 10 000€. Pour accéder à la console SQL.
Il est possible d'utiliser dans une même requête la clause WHERE et la clause HAVING.
Pour identifier les clients ayant passé plus de 5 commandes en France, il est essentiel de définir d'abord le contexte géographique avec la clause WHERE, puis de vérifier si le nombre de commandes dépasse 5 avec la clause HAVING.
/* Afficher les clients ayant effectué plus de 5 commandes en France */
SELECT customerKey, COUNT(salesOrderNumber) as nOrder
FROM factInternetSale
WHERE SalesTerritoryKey = 7 --7 correspond à la France
GROUP BY customerKey
HAVING COUNT(salesOrderNumber) > 5 ;Voici l'ordre d'exécution de la requête :
WHERE : Filtre les lignes de données en ne sélectionnant que celles où la condition spécifiée est vraie. Ici, la condition est que la clé du territoire de vente (SalesTerritoryKey) doit être égale à 7, ce qui correspond à la France.
GROUP BY : Regroupe les lignes en fonction de la clé du client (customerKey).
HAVING : Agit comme un filtre supplémentaire, ne renvoyant que les groupes pour lesquels le nombre de commandes est supérieur à 5.
SELECT : Spécifie les colonnes que vous souhaitez inclure dans les résultats, dans ce cas, customerKey et le nombre d'ordres (nOrder ).
En résumé, l'ordre d'exécution est FROM, WHERE, GROUP BY, HAVING et enfin SELECT.
Question 10.4
Dans la table factInternetSale, affiche tous les clients ayant commandé pour plus de 10 000€ de produits sur l'année 2014.
Question 10.5
Dans la table factInternetSale, affiche les 10 premiers clients (par nombre de commande puis par ordre de numero d'identifiants) ayant effectués le plus de commandes et dont le montant total des commandes est supérieur à 10 000€ sur l'année 2014.
SQL Console
| Category | Num | Sales Usd |
|---|---|---|
| ABC | 123 | $26.4M |