[MySQL] sélectionner la dernière note pour chaque élève en une seule requète ?

swakone

Nouveau WRInaute
Bonjour à tous,

il y a une requete sql que je n'arrive pas a formuler correctement :
J'ai une table avec la liste des notes obtenues par tous les élèves d'une classe (id_eleve, note, date).

J'essaie de sélectionner la dernière note que l'élève a eu dans l'année, mais je n'y arrive pas...

j'ai essayé quelque chose comme

select note, max(date) from notes group by id_eleve

mais je n'ai pas l'impression que note et max(date) soit réellement corrélés ?!

Merci de votre aide !!

Frédéric
 

swakone

Nouveau WRInaute
@zeb dans cette requete, je n'ai pas l'information par élève, mais simplement la note la plus récente, hors il me la faut par élève

@ZelkiN le problème c'est que je ne veux pas la note pour 1 élève donné (je ne connais pas $id_eleve), mais pour tous les élèves.

je pourrais faire une requete dans la boucle d'une autre, mais c'est pas super optimisé niveau performance... je me demande s'il n'y a pas une solution pour faire une requete propre en sql...
 

zeb

WRInaute accro
swakone a dit:
@zeb dans cette requete, je n'ai pas l'information par élève, mais simplement la note la plus récente, hors il me la faut par élève
bah tu rajoute le champ élève .... :D

select note,id_eleve from notes where date = max(date)

et si des fois le nom de l'élève est dans une autre table et que id_eleve est une fk de cette table du genre autre_table[id_eleve, nom, prenom] tu fait :

SELECT B.nom, B.prenom, A.note
FROM notes as A, autre_table as B
WHERE A.date = max(A.date) AND A.id_eleve = B.id_eleve

et si tu veux faire propre tu donne un ordre de trie a la fin du genre :

ORDER BY B.nom, B.prenom

Ralala ! ces profs faut tout leur expliquer :D :wink:
donne nous plus de détails sur ta structure si ça coince.

Amicalement
 

Supermaury

WRInaute discret
C'est vrai que si on a deux tables (et ça doit ête le cas), Zeb a résolu le problème.
Par contre j'avoue que j'ai bien galéré à trouver la solution si on se base seulement sur la table NOTES.
Essaie ça dans ce cas (c'est ok sous Sql Server mais je n'ai pas testé sous MySql) :

SELECT ID_ELEVE, NOTE, DATE FROM NOTES
JOIN (SELECT MAX(DATE) AS DTMP, ID_ELEVE AS IDTMP FROM NOTES GROUP BY ID_ELEVE) AS TEMP
ON NOTES.ID_ELEVE=TEMP.IDTMP AND NOTES.DATE=TEMP.DTMP
ORDER BY ID_ELEVE

@++
 

swakone

Nouveau WRInaute
Code:
#1111 - Utilisation invalide de la clause GROUP
:D

Par contre, à première vue,
select note,id_eleve from notes where date = max(date) :arrow: je ne vois pas pourquoi cela me retournerait une info PAR élève, si ? J'ai essayé d'ajouter un GROUP BY, mais j'ai toujours l'erreur ci dessus.

Ralala ! ces profs faut tout leur expliquer :D :wink:
Je suis loin d'être prof :wink:
C'est en réalité pour un logiciel de gestion de trésorerie, ou je dois sélectionner une date de dernier mouvement pour chaque type d'opération, mais ça m'a parut bien plus simple à expliquer avec des notes et des élèves !

Pour supermaury : en effet ta solution m'a l'air de fonctionner à merveille !

voici le code final :

Code:
SELECT op_titre, date_facturation, op_type
FROM treso_vue_1806_operations
JOIN (
SELECT MAX( date_facturation ) AS DTMP, op_type AS id_op_tmp
FROM treso_vue_1806_operations
GROUP BY op_type
) AS TEMP ON treso_vue_1806_operations.op_type = TEMP.id_op_tmp
AND treso_vue_1806_operations.date_facturation = TEMP.DTMP
GROUP BY treso_vue_1806_operations.op_type

J'ai du ajouter un GROUP BY op_type, car si j'ai plusieurs opérations avec un même op_type à une date donnée (qui est le max(date) qui plus est...) il me les retourne toutes ! (ce qui aurait pu être le cas si on a plusieurs notes pour un même élève à une même date, mais c'est bien moins probable :D )

Merci à vous et très bonne soirée !

Frédéric
 

Blount

WRInaute impliqué
Personnellement, j'aurai fait ceci :
Code:
SELECT ID_ELEVE, NOTE, DATE
FROM NOTES 
GROUP By ID_ELEVE
ORDER By DATE DESC

Ça tri la table de plus récent ou plus ancien. Ensuite, le GROUP BY permet de ne garder qu'une ligne par élève. Dans cette opération, seul la plus récente reste car il groupe de bas en haut en écrasant à chaque fois les valeurs des colonnes.
Ça effectue donc un LIMIT 1 pour chaque élève.
 

Neshival

Nouveau WRInaute
Blount a dit:
Personnellement, j'aurai fait ceci :
Code:
SELECT ID_ELEVE, NOTE, DATE
FROM NOTES 
GROUP By ID_ELEVE
ORDER By DATE DESC
J'ai testé ceci mais vu que le group by est effectué avant le order, on se retrouve avec la date la plus ancienne pour chaque eleve.

Code:
SELECT * FROM (
 SELECT ID_ELEVE, NOTE, DATE
 FROM NOTES 
 ORDER By DATE DESC
) as NOTES2
GROUP By ID_ELEVE

De cette maniere on a bien la note la plus récente pour chaque eleve.
cordialement
 

Discussions similaires

Haut