Trier selon une moyenne

Eléphanteau du PHP | 26 Messages

31 mars 2022, 11:14

Bonjour à tous,

Principe :
concours de poésie, avec une liste de poèmes (table 1)
chaque poème reçois des points (table 2)

je cherche à trier mes poèmes selon le nombre de points obtenus.

Actuellement :
j'affiche ma liste de poème dans le désordre, puis à côté de chaque poème je calcule son nombre de points (enfin sa moyenne de points)

LE CODE

Code : Tout sélectionner

$req1 = ' SELECT * FROM concours2020 WHERE finale=1 ORDER BY RAND() '; $result1 = mysqli_query($bdd,$req1) or die ('Execution de la sélection impossible1'); while($liste = mysqli_fetch_array($result1,MYSQLI_BOTH)) { $reqnb = 'SELECT SUM(points) FROM concours2020finale WHERE idpoeme ='.$liste["id"].''; $resultnb = mysqli_query($bdd,$reqnb) or die ('Execution de la sélection impossible4'); $nbpoints = mysqli_fetch_array($resultnb,MYSQLI_BOTH); $reqnv = 'SELECT * FROM concours2020finale WHERE idpoeme ='.$liste["id"].''; $resultnbv = mysqli_query($bdd,$reqnv) or die ('Execution ici impossible5'); $nbv = mysqli_num_rows($resultnbv); if ($nbv!=0) { $moyenne = ($nbpoints[0] / $nbv); $moyenne = round( $moyenne, 2, PHP_ROUND_HALF_UP); } else { $moyenne = "Pas de note"; } echo ' <p align="center"> <a href="concours2020poemefinaliste.php?numpoeme='.$liste["id"].'" >Poème '.$liste["id"].'</a> (Moyenne = '.$moyenne.')</p> '; }

Comment faire pour arriver à calculer la moyenne avant et faire le tri à partir de cela ?

Merci pour votre coup de main

ynx
Mammouth du PHP | 586 Messages

01 avr. 2022, 11:34

Bonjour,

Une solution possible en PHP : au lieu d'afficher directement les poèmes dans ta boucle while, tu pourrais enregistrer les poèmes et leurs moyennes dans un tableau. Puis, après la boucle while, utiliser une fonction pour trier ce tableau de poèmes selon la moyenne et enfin créer une deuxième boucle pour parcourir et afficher les poèmes depuis ce tableau trié.

Une autre (meilleure ?) solution serait, si possible, d'effectuer le calcul de la moyenne et le tri directement dans la requête sql. Si tu pouvais partager la structure de la bdd avec quelques données d'exemples, on pourrait p-e mieux comprendre comment sont organisées les données afin de proposer une solution en sql.

Bonne journée,

Eléphanteau du PHP | 26 Messages

03 avr. 2022, 21:54

Merci pour ce retour,

donc si j'ai bien compris la solution serait plutôt en PHP avec la technique de la création d'un tableau à partir de la bdd. J'ai toujours du mal à comprendre comment ça fonctionne vraiment, pourtant j'essaye d'apprendre, mais je n'ai pas autant de facilités que certains d'entre vous (qui méritent leur connaissances)...

Pour ce qui est de la BDD c'est assez simple :

Table 1 : Concours2020
id, pseudo, poeme, finale

Table 2 : Concours2020finale
id, idpoeme, votant, points

idpoeme dans table2 correspond à id dans table1

et la moyenne se fait sur le total de points

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

06 avr. 2022, 13:55

Ça devrait être faisable en SQL.
Mon conseil : fais d'abord tes tests de requêtes dans phpmyadmin, et une fois que ta requête fonctionnera tu la mettras dans du code PHP.


Etape 1, il faut que tu calcules la moyenne de tes poêmes en utilisant ta table2 :

En SQL pour calculer une moyenne de plusieurs enregistrements, il faut utiliser la fonction AVG() :
https://sql.sh/fonctions/agregation/avg

Par contre, tu ne veux pas calculer la moyenne générale de tous les poèmes, mais celle de chaque poème, du coup il faut que tu utilises la directive GROUP BY idpoeme
https://sql.sh/cours/group-by

Et enfin tu voudras trier les résultats pour avoir le poème avec la moyenne la + haute en premier.
Ça se fait avec la directive ORDER BY et en précisant DESC pour aller du plus grand au plus petit.
https://sql.sh/cours/order-by

Mais pour faire ce tri tu as besoin d'indiquer le nom de la colonne sur laquelle se fait le tri or vu que ce nom est le résultat de la fonction AVG() du coup il faut que tu la nommes explicitement comme ceci AVG(points) AS moyenne

Une fois que tu as fait tout ça tu dois obtenir la liste des idpoeme avec leur moyenne triée dans le bon ordre.
Quand c'est bon, il te faudra faire une jointure avec ta table1 pour ajouter le nom du poeme
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 26 Messages

07 avr. 2022, 14:22

Bonjour,

j'ai testé

Code : Tout sélectionner

SELECT AVG(points) AS moyenne FROM concours2020finale GROUP BY idpoeme ORDER BY moyenne DESC
et j'obtiens un tableau d'une seule colonne (moyenne) avec des nombres classés dans l'ordre décroissant.

L'idpoeme n'apparait pas dans ce tableau.
De plus j'ai l'impression que ce n'est pas une moyenne que j'obtiens

Le pire dans tout cela c'est que la jointure me parait plus difficile, car avec mon code de départ j'arrivais à obtenir la moyenne par idpoeme.

Merci dans tous les cas pour la tentative d'aide. Je crois que je vais prendre ma retraite.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

07 avr. 2022, 19:58

Du coup il faut que tu demandes dans ta requête à avoir l'idpoeme en plus de la moyenne :
SELECT idpoeme, AVG(...
Quand tout le reste a échoué, lisez le mode d'emploi...