Combien rapporte chaque rayon ?
GROUP BY range les lignes d'une table en groupes, pour que COUNT, SUM et AVG donnent un résumé par groupe.
Tu passes ainsi de milliers de lignes à une réponse courte, comme les ventes de chaque rayon de la cantine. C'est ce que fait n'importe quel tableau de bord de vente.
À la fin de cette leçon
Remarque
Je peux résumer les lignes d'une table avec COUNT, SUM et GROUP BY.
Mots clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Agrégat | un calcul qui résume plusieurs lignes en une valeur | COUNT(*) |
| COUNT | compte les lignes | |
| SUM | additionne les valeurs d'une colonne | |
| Groupe | les lignes qui ont la même valeur dans une colonne | |
| GROUP BY | range les lignes en groupes avant de calculer | GROUP BY country |
| HAVING | garde seulement les groupes qui réussissent un test |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Les agrégats résument plusieurs lignes
Un agrégat est un calcul qui prend plusieurs lignes et rend une seule valeur. COUNT compte, SUM additionne, AVG fait la moyenne, MIN et MAX donnent le plus petit et le plus grand.
COUNT(*) compte toutes les lignes. COUNT(phone) compte seulement celles où le téléphone n'est pas NULL.
Avant de commencer
Remarque
Appuie sur Start the lab dans la barre en haut et attends que la machine soit prête. Les deux Runs suivants servent à te connecter. Le deuxième crée un alias : un nom court, sql, pour une longue commande.
Accepter le certificat du serveur
printf '[client]\nssl-verify-server-cert=0\n' > ~/.my.cnfAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Un nom court pour la boutique
alias sql='mariadb -h db -u student -pstudent shop -t -e'Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Compter les clients et leurs téléphones
sql "SELECT COUNT(*) AS nb, COUNT(phone) AS avec_telephone FROM customers"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Total et prix extrêmes des commandes
sql "SELECT SUM(quantity) AS articles_vendus, MIN(unit_price) AS plus_bas, MAX(unit_price) AS plus_haut FROM order_items"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Exemple : cinq agrégats sur trois prix
| Agrégat | Ce qu'il calcule | Résultat |
|---|---|---|
| COUNT(*) | Le nombre de lignes | 3 |
| SUM(prix) | La somme | 18 |
| AVG(prix) | La moyenne | 6 |
| MIN(prix) | Le plus petit | 4 |
| MAX(prix) | Le plus grand | 8 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
GROUP BY calcule un résultat par groupe
Un agrégat seul résume toute la table. Avec GROUP BY, la base range d'abord les lignes en groupes : une ligne par valeur de la colonne choisie. Puis elle calcule l'agrégat dans chaque groupe.
Tout ce que tu écris dans SELECT est ou bien la colonne du groupe, ou bien un agrégat.
Exemple : comment la base forme les groupes
| Ligne | country | Groupe | Compte après le groupement |
|---|---|---|---|
| 1 | France | France | France : 2 |
| 2 | Japan | Japan | Japan : 1 |
| 3 | France | France | France : 2 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Combien de commandes dans chaque état ?
sql "SELECT status, COUNT(*) AS nb FROM orders GROUP BY status ORDER BY nb DESC"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Nombre d'articles et prix moyen par rayon
sql "SELECT c.name AS rayon, COUNT(*) AS nb_articles, ROUND(AVG(p.price), 2) AS prix_moyen FROM products p JOIN categories c ON c.id = p.category_id GROUP BY c.name ORDER BY c.name"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Les trois commandes les plus chères
sql "SELECT order_id, SUM(quantity * unit_price) AS total FROM order_items GROUP BY order_id ORDER BY total DESC, order_id LIMIT 3"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
WHERE filtre les lignes, HAVING filtre les groupes
WHERE agit avant le groupement : il écarte des lignes. HAVING agit après : il écarte des groupes entiers, d'après leur agrégat.
Pour ne garder que les pays qui ont au moins 8 clients, on écrit HAVING COUNT(*) >= 8.
Les clients inscrits depuis 2024, par pays
sql "SELECT country, COUNT(*) AS nb FROM customers WHERE joined_on >= '2024-01-01' GROUP BY country ORDER BY nb DESC, country"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Les pays qui ont au moins 8 clients
sql "SELECT country, COUNT(*) AS nb FROM customers GROUP BY country HAVING COUNT(*) >= 8 ORDER BY nb DESC, country"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Un agrégat dans WHERE : la base refuse
sql "SELECT country, COUNT(*) AS nb FROM customers WHERE COUNT(*) >= 8 GROUP BY country"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une erreur fréquente
Attention
Beaucoup pensent que WHERE et HAVING font le même travail. WHERE s'exécute avant le groupement, donc il ne connaît pas encore COUNT. Teste une colonne ordinaire avec WHERE. Teste un agrégat avec HAVING.
À toi : les ventes de la cantine
-- Combien d'articles chaque rayon a-t-il vendus ?
SELECT p.rayon, SUM(v.quantite) AS articles
FROM ventes v
JOIN produits p ON p.id = v.produit_id
GROUP BY p.rayon
ORDER BY p.rayon;
-- Ajoute HAVING SUM(v.quantite) > 30 avant ORDER BY : quels rayons restent ?