informatique (MP2I/MPI) · Chapitre 21 · Application directe du cours
La moyenne pondérée, et deux façons de la rater
Bases de données relationnelles et SQL · niveau 2
Énoncé
Chaque matière a un coefficient. Écrire la moyenne pondérée de chaque élève. Que valent, à côté, AVG(n.valeur) et AVG(n.valeur * m.coef) ?
Corrigé
La moyenne pondérée est , et elle s'écrit avec deux sommes :
SELECT e.nom,
SUM(n.valeur * m.coef) * 1.0 / SUM(m.coef) AS ponderee
FROM Eleve e JOIN Note n ON n.eleve = e.id
JOIN Matiere m ON m.code = n.matiere
GROUP BY e.id, e.nom;
| nom | pondérée | AVG(valeur) | AVG(valeur*coef) | ||
|---|---|---|---|---|---|
| Alaoui | |||||
| Benali | |||||
| Cohen |
Tous ces nombres sont mesurés. Trois observations.
1. AVG(n.valeur) est la moyenne simple, et elle est différente : contre pour Alaoui. La pondération l'a fait baisser, puisque son pèse un coefficient et son un coefficient . La moyenne simple n'est pas « approximativement » la pondérée : elle répond à une autre question.
2. AVG(n.valeur * m.coef) n'a aucun sens. Elle vaut pour Alaoui — une note sur ne vaut pas . Elle calcule , en divisant par le nombre de notes au lieu de la somme des coefficients. Une fonction d'agrégation divise toujours par le nombre de lignes ; si le dénominateur voulu est autre chose, il faut l'écrire. C'est pourquoi une moyenne pondérée s'écrit avec deux SUM et jamais avec un AVG.
3. Le * 1.0 n'est pas décoratif. Sans lui, est une division entière et rend au lieu de . Mesuré sur la moyenne générale : SUM(valeur)/COUNT(*) rend , là où AVG(valeur) rend .
C'est très exactement le piège de l'exercice 1.1 : double b = 7 / 2; vaut parce que la division est faite avant la conversion. Le programme dit ici « on passe outre les subtilités liées à la division entière ou flottante » — ce qui autorise à ne pas les théoriser, pas à s'y laisser prendre. Deux entiers divisés donnent un entier, dans tous les langages de ce livre.