SQL Quest
Se connecter English 0 XP Niv. 1
Intermédiaire

SQL GROUP BY : calculer par groupe

4 min de lecture · 4 exemples exécutables · mis à jour le 9 octobre 2026

Les fonctions d'agrégation résument toute une table en une seule valeur. Mais on veut souvent un résultat par catégorie : le nombre de clients par ville, le chiffre d'affaires par mois, le salaire moyen par département. C'est le rôle de GROUP BY.

Syntaxe

SELECT colonne_de_groupe, FONCTION(colonne)
FROM table
GROUP BY colonne_de_groupe;

Comment ça marche

GROUP BY rassemble les lignes qui ont la même valeur dans la colonne indiquée, puis applique la fonction d'agrégation à chaque groupe. Le résultat contient une ligne par groupe.

La règle d'or

Chaque colonne du SELECT doit soit figurer dans le GROUP BY, soit être à l'intérieur d'une fonction d'agrégation. Sinon, SQL ne saurait pas quelle valeur afficher pour un groupe qui contient plusieurs lignes différentes.

L'ordre d'exécution d'une requête

SQL n'exécute pas les clauses dans l'ordre où on les écrit :

  1. FROM (et les JOIN) : on part des tables ;
  2. WHERE : on filtre les lignes ;
  3. GROUP BY : on forme les groupes ;
  4. HAVING : on filtre les groupes ;
  5. SELECT : on calcule les colonnes ;
  6. ORDER BY puis LIMIT.

Comprendre cet ordre explique la plupart des erreurs : par exemple, on ne peut pas utiliser un COUNT dans le WHERE, car les groupes n'existent pas encore à ce moment-là.

Schéma

clients
prenomville
LéaLyon
InèsLyon
HugoParis
AdamLyon
ZoéParis
résultat
villeCOUNT(*)
Lyon3
Paris2
GROUP BY ville : les lignes de même ville forment un groupe, et COUNT(*) compte chaque groupe.

Schéma simplifié pour illustrer le principe. Les exemples ci-dessous utilisent la vraie base d'exercices de SQL Quest (une boutique en ligne fictive : voir le schéma complet).

Exemples avec leurs résultats

1. Compter par groupe

Le nombre de clients par ville, de la plus peuplée à la moins peuplée.

SELECT ville, COUNT(*) AS nb_clients
FROM clients
GROUP BY ville
ORDER BY nb_clients DESC;
Essayer dans le bac à sable
Résultat
villenb_clients
Bordeaux14
Paris13
Lyon12
Strasbourg11
Nantes10
Montréal10
Marseille10
Lille10
Casablanca10
Bruxelles9

12 lignes au total · 10 affichées

2. Plusieurs agrégations par groupe

Pour chaque catégorie : le nombre de produits et le prix moyen.

SELECT categorie, COUNT(*) AS nb_produits, ROUND(AVG(prix), 2) AS prix_moyen
FROM produits
GROUP BY categorie;
Essayer dans le bac à sable
Résultat
categorienb_produitsprix_moyen
Alimentation524,74
Informatique7146,43
Livres518,17
Maison636,45
Sport627,81

5 lignes au total

3. Grouper sur une expression

Le nombre de commandes par année, grâce à strftime qui extrait l'année d'une date.

SELECT strftime('%Y', date_commande) AS annee, COUNT(*) AS nb_commandes
FROM commandes
GROUP BY annee;
Essayer dans le bac à sable
Résultat
anneenb_commandes
2023190
2024214
2025196

3 lignes au total

4. Grouper sur deux colonnes

Le nombre de commandes par année et par statut.

SELECT strftime('%Y', date_commande) AS annee, statut, COUNT(*) AS nb
FROM commandes
GROUP BY annee, statut
ORDER BY annee, nb DESC
LIMIT 8;
Essayer dans le bac à sable
Résultat
anneestatutnb
2023livrée85
2023annulée39
2023en cours34
2023expédiée32
2024livrée117
2024expédiée35
2024en cours34
2024annulée28

8 lignes au total

Les erreurs fréquentes

Afficher une colonne qui n'est pas groupée

nom n'est ni dans le GROUP BY ni dans une agrégation : SQLite affiche un nom au hasard du groupe, les autres bases renvoient une erreur.

À éviter
SELECT ville, nom, COUNT(*) FROM clients GROUP BY ville;
Correct
SELECT ville, COUNT(*) FROM clients GROUP BY ville;

Oublier le GROUP BY

Sans GROUP BY, la requête renvoie une seule ligne pour toute la table au lieu d'une ligne par ville.

À éviter
SELECT ville, COUNT(*) FROM clients;
Correct
SELECT ville, COUNT(*) FROM clients GROUP BY ville;

Grouper sur une colonne trop précise

Grouper par id crée un groupe par ligne : le regroupement ne sert à rien.

À éviter
SELECT id, ville, COUNT(*) FROM clients GROUP BY id;
Correct
SELECT ville, COUNT(*) FROM clients GROUP BY ville;

Exercices

Essayez d'écrire la requête vous-même avant d'ouvrir la solution.

Défi 1. Affichez le salaire moyen par département, arrondi à l'euro.

Voir une solution
SELECT departement, ROUND(AVG(salaire)) AS salaire_moyen FROM employes GROUP BY departement;
departementsalaire_moyen
Direction9 500
IT4 760
RH4 233
Ventes4 554

4 lignes au total

Essayer dans le bac à sable

Défi 2. Affichez le nombre de produits par fournisseur (fournisseur_id, nombre).

Voir une solution
SELECT fournisseur_id, COUNT(*) AS nb FROM produits GROUP BY fournisseur_id;
fournisseur_idnb
11
22
34
413
51
65
73

7 lignes au total

Essayer dans le bac à sable
Envie de vous entraîner davantage ?

Les exercices interactifs sont corrigés automatiquement, avec un prof qui explique vos erreurs. Une leçon résumée reste affichée à côté de l'éditeur.

Faire les exercices interactifs

Questions fréquentes

Quelle différence entre GROUP BY et ORDER BY ?

GROUP BY rassemble les lignes pour calculer une valeur par groupe (le nombre de lignes diminue). ORDER BY ne fait que trier les lignes, sans en changer le nombre.

Peut-on utiliser un alias dans GROUP BY ?

SQLite, MySQL et PostgreSQL l'acceptent (GROUP BY annee). Le SQL standard et SQL Server demandent de répéter l'expression.

Comment filtrer les groupes ?

Avec HAVING, placé après GROUP BY : HAVING COUNT(*) > 10 ne garde que les groupes de plus de 10 lignes.

À lire ensuite