Calcul de rang
Comment obtenir le rang de personnes, en tenant compte des ex-æquo ? L’idée étant de classer les participants à une épreuve sportive, ou des élèves à partir de leurs notes…
Le principe
On dispose d’une table simple avec une valeur numérique ou une valeur de temps, qui doit servir à établir un classement. Dans notre exemple (super classique !), il s’agit d’une liste d’élèves avec leur note moyenne. L’objectif est de classer ces élèves en fonction de leur note, et de calculer le rang de chaque élève (du 1er au dernier).
Le principe général consiste à compter, pour chaque élève, combien d’élèves ont une moyenne supérieure. Et à ajouter 1 pour ajuster le rang (le meilleur élève n’a personne au-dessus de lui, il aurait un rang de 0 sinon).
Mais sur Access, ce n’est pas aussi simple que sur Excel !
Méthode 1 : calcul de rang par DCount
Une première solution consiste à utiliser la fonction DCount()
, ou CpteDom()
en français :
- Créez une requête basée sur la table
tblElèves
. - Ajoutez à votre requête le champ calculé suivant :
Rang: CpteDom("*";"[tblElèves]";"[Moyenne] > " & [Moyenne]) + 1
Vous obtenez ceci en mode Création (si vous y voyez quelque chose !) :
Une fois exécutée, la requête affiche ceci :
Quelques remarques :
- Pour l’affichage, vous ajouterez généralement un tri décroissant sur les moyennes (ou croissant sur le rang). Mais ceci n’a pas d’impact sur le calcul lui-même, c’est juste pour faire lisible !
- Lorsqu’il y a des ex-æquo, on considère ici que l’un des rangs est « brûlé ». Ainsi, comme il y a 2 élèves classés 1, le rang 2 est brûlé. Le troisième élève est donc classé 3. C’est normal, puisqu’on compte toutes les moyennes supérieures : l’élève 3 a bien 2 élèves meilleurs que lui, l’élève 7 a 6 élèves meilleurs que lui.
Méthode 2 : calcul de rang par sous-requête
Les fonctions de domaine – dont DCount()
– sont généralement peu performantes. Vous pouvez remplacer le calcul précédent par une sous-requête (ou « subquery »). Le résultat sera le même que précédemment. Le champ calculé devient alors :
Rang: (SELECT Count(*) FROM [tblElèves] AS T2 WHERE T2.[Moyenne] > T1.[Moyenne]) + 1
Note : la table utilisée dans la requête est renommée T1
pour clarifier la syntaxe de la sous-requête. Pour renommer une table (en fait, pour lui donner un « alias »), faites comme ceci :
- Cliquez sur la table du bouton droit de la souris (la table placée en haut de la requête).
- Cliquez sur l’option Propriétés.
- Dans la zone Alias, tapez
T1
.
Méthode 3 : variante sur la numérotation
Maintenant, je vous vois arriver 🙂 : vous allez vouloir numéroter les élèves sans brûler de numéros. Ça complique un peu la sous-requête, parce qu’il faut :
- Extraire les moyennes différentes « au-dessus » d’un élève. La clause SQL
DISTINCT
est votre amie… - Les décompter.
- Ajuster comme plus haut, en ajoutant 1.
Le calcul du rang devient :
1 2 3 4 |
Rang: (SELECT COUNT(*) + 1 FROM (SELECT DISTINCT [Moyenne] FROM [tblElèves] AS T2) WHERE T2.[Moyenne] > [tblElèves].[Moyenne] ) |
On obtient ce résultat :
Variante : calculer un rang basé sur un temps
Si vous devez calculer un rang basé sur le temps, le principe est le même, mais vous changerez 2 choses :
- Les tris sont inversés (une bonne moyenne est grande, mais un bon temps est petit !).
- Les signes
>
deviennent des signes < pour la même raison.
Merci
Bravo Excellent tuto.
Merci ! 🙂
La fonction: Rang: CpteDom(« * »; »[tblElèves] »; »[Moyenne] > » & [Moyenne]) + 1 marche impeccable, mais je voudrais l’adapter à plusieurs (2 ou 3) critères de classement, du style classement d’un championnat de foot, sur le nombre de points, puis sur le goal-average, puis sur le nombre de buts marqués.
merci d’avance
A vue de nez (mais je n’ai pas tous les paramètres), il faudrait adapter la dernière partie de la fonction par concaténations. Du style :
Je suis parti du principe que tous les champs étaient numériques.
A adapter en fonction des champs de la table Je n’ai pas de quoi vérifier que ça marche, mais c’est déjà une piste… 🙂
ahmed > Cet autre article du Grenier devrait aider.
merci
mais j’ai un problème c est que apres le rang comment afficher les 4 meilleurs
demba > Cet article publié mardi devrait aider.
Bonjour à tous;
J’ai essayé l’exemple du site, ma requête affiche un message d’erreur #Erreur avec le 1er enregistrement « Inisan Hervé 8.5 » Mais si j’enlève le décimal, ça passe. Je peux avoir des explications?
fourchette2 > Il y a 2 manières de traiter ce problème :
Ouala !
pour le calcul de rang sans critéres lorsque j’ applique la formule acces rang les entiers mais pas les decimaux ou peut-donc se situer le probleme aider mw
dabafa > Ben… pour le rang, c’est expliqué dans l’article, précisément. 😉
Pour la moyenne, si elle est non coefficientée, tu peux faire une requête de regroupement sur les notes, avec un calcul de moyenne appliqué au champ
Note
.comment calculer le rang et la moyenne de tes notes
Yedegue > Oui, c’est normal : on calcule un rang numérique. Si tu veux un affichage texte, il est possible de créer une fonction VBA pour ça, ou une table de correspondance (si la liste est limitée seulement). D’autant que ça serait différent en anglais, par exemple : 1st, 2nd, 3rd…
Le sql permet de faire le rang mais, juste ecrire 1;2;3;4… ne permet pas d’ecrire les rangs 1er ; 2ème; 3ème….
merci beaucoup
paptagne > Exact, les requêtes de l’article ne sont pas prévues pour ce cas de figure. J’ai ajouté un nouvel article qui dit comment faire, c’est par ici :-).
La fonction ne marche pas avec une requête paramétrée « Entrer la classe » par exemple.