informatique (MP2I/MPI) · Chapitre 21 · Application directe du cours
COUNT(*) et COUNT(colonne) : deux comptages, deux réponses
Bases de données relationnelles et SQL · niveau 2
Énoncé
Le cours annonce que « deux comptages sur la même table peuvent légitimement différer ». Le mettre en évidence, puis expliquer lequel répond à « combien Dupont a-t-il de notes ? ».
Corrigé
SELECT COUNT(*) FROM Eleve e LEFT JOIN Note n ON n.eleve = e.id; -- 6
SELECT COUNT(n.valeur) FROM Eleve e LEFT JOIN Note n ON n.eleve = e.id; -- 5
Six contre cinq, mesuré. La jointure externe produit six lignes ; la sixième, celle de Dupont, porte une valeur NULL. COUNT(*) compte les lignes, COUNT(colonne) compte les valeurs présentes dans cette colonne.
Par élève, l'écart se localise :
SELECT e.nom, COUNT(*) AS avec_etoile, COUNT(n.valeur) AS avec_colonne
FROM Eleve e LEFT JOIN Note n ON n.eleve = e.id
GROUP BY e.id, e.nom ORDER BY e.id;
| nom | COUNT(*) | COUNT(n.valeur) |
|---|---|---|
| Alaoui | 2 | 2 |
| Benali | 2 | 2 |
| Cohen | 1 | 1 |
| Dupont | 1 | 0 |
C'est COUNT(n.valeur) qui répond à la question, et il répond . La colonne COUNT(*) rend pour Dupont — ce compte la ligne fabriquée par la jointure externe, pas une note.
Ce qu'il faut retenir, et c'est un réflexe : après un LEFT JOIN, ne jamais compter avec COUNT(*). Le de Dupont est le défaut classique du « nombre d'articles par client » : tout client sans commande en aurait un. On compte une colonne de la table de droite, et le apparaît.