Niveau 7 : Regrouper avec GROUP BY
Mis à jour le
Intermédiaire · niveau 7 sur 20. Objectif : Calculer un agrégat pour chaque groupe de lignes : total par vendeur, moyenne par matière…
Notions : GROUP BY agrégats par groupe regroupement sur plusieurs colonnes
Leçon
Les agrégats du niveau 5 résument toute la table. Souvent, on veut plutôt un résumé par catégorie : le total de chaque vendeur, la moyenne de chaque matière, le nombre de films de chaque genre. C'est le rôle de GROUP BY.
GROUP BY region fonctionne en trois temps. D'abord, SQL range les lignes en paquets : toutes les ventes dont la région vaut 'North' dans un paquet, toutes celles de 'South' dans un autre. Ensuite, il calcule les agrégats séparément dans chaque paquet. Enfin, il rend une seule ligne par paquet. Les 12 ventes deviennent ainsi 2 lignes : North avec un total de 2600, South avec 2450.
D'où la règle d'or : dans le SELECT, chaque colonne doit soit figurer dans le GROUP BY, soit être dans un agrégat. Une ligne de résultat représente un paquet entier. La région est la même pour tout le paquet : on peut l'afficher. Le montant change d'une vente à l'autre : on ne peut afficher que sa somme, sa moyenne ou son maximum. Une colonne qui ne respecte pas la règle n'a pas de valeur unique à afficher.
On peut regrouper sur plusieurs colonnes : GROUP BY region, month crée un paquet par couple (région, mois). Les lignes dont la colonne de regroupement vaut NULL forment un paquet à part.
GROUP BY ne trie pas le résultat : ajoute ORDER BY si l'ordre compte.
L'ordre d'exécution s'enrichit : FROM, WHERE (filtre les lignes), GROUP BY (forme les paquets), SELECT (calcule une ligne par paquet), ORDER BY. Le WHERE agit donc avant le regroupement : avec WHERE month = '2025-01', seules les ventes de janvier sont réparties dans les paquets.
Syntaxe
SELECT colonne_groupe, COUNT(*), SUM(x)
FROM ma_table
WHERE …
GROUP BY colonne_groupe
ORDER BY …;Exemple commenté
SELECT region, SUM(amount) AS total
FROM sales
GROUP BY region;Les 12 ventes sont réparties en deux groupes (North et South) ; SUM est calculé dans chacun.
| id | seller | region | month | amount |
|---|---|---|---|---|
| 1 | Ana | North | 2025-01 | 300 |
| 2 | Ana | North | 2025-02 | 450 |
| 3 | Ana | North | 2025-03 | 400 |
| 4 | Ben | North | 2025-01 | 500 |
| 5 | Ben | North | 2025-02 | 350 |
| 6 | Ben | North | 2025-03 | 600 |
| 7 | Cleo | South | 2025-01 | 200 |
| 8 | Cleo | South | 2025-02 | 700 |
| 9 | Cleo | South | 2025-03 | 650 |
| 10 | Dan | South | 2025-01 | 400 |
| 11 | Dan | South | 2025-02 | 400 |
| 12 | Dan | South | 2025-03 | 100 |
Résultat de l’exemple
| region | total |
|---|---|
| North | 2600 |
| South | 2450 |
À retenir
- Une ligne de résultat par groupe.
- Colonnes du SELECT : dans le GROUP BY ou dans un agrégat.
- WHERE filtre les lignes avant le regroupement.
Pièges fréquents
- SELECT seller, region, SUM(amount) … GROUP BY seller : region n'est ni regroupée ni agrégée. La plupart des moteurs refusent la requête.
- Oublier GROUP BY donne une seule ligne pour toute la table.
Spécificité SQLite
SQLite accepte une colonne ni regroupée ni agrégée : il affiche la valeur d'une ligne quelconque du groupe, sans prévenir. Le résultat semble correct mais peut être faux : applique toujours la règle d'or.
Pour aller plus loin
GROUP_CONCAT(title, ', ') colle toutes les valeurs d'un groupe en un seul texte, par exemple la liste des titres de chaque genre (STRING_AGG dans PostgreSQL et SQL Server ; SQLite accepte aussi string_agg depuis la version 3.44).
Les 5 exercices du niveau
- Affiche le total des ventes (amount) de chaque vendeur (seller).
- Affiche le nombre d'employés de chaque service.
- Affiche la moyenne des notes de chaque matière, arrondie à une décimale.
- Affiche le total des ventes pour chaque couple région et mois.
- Parmi les livres publiés à partir de 2015, affiche le nombre de livres par genre, du genre le plus représenté au moins représenté (en cas d'égalité, par ordre alphabétique du genre).
Dans SpeedQL, chaque requête est corrigée tout de suite : le résultat est comparé à celui attendu, puis la requête est relancée sur une base de contrôle cachée. Chaque exercice a ses indices écrits, à afficher seulement si tu bloques.
Voir aussi : la fiche de l’aide-mémoire · les exercices SQL corrigés sur cette notion
Faire les exercices du niveau 7
Gratuit, sans inscription : la leçon et les 5 exercices s’ouvrent directement dans ton navigateur.
← Niveau précédent : Travailler le texte et les dates · Niveau suivant : Filtrer les groupes avec HAVING →