SQL : regrouper des enregistrements - SQL/NoSQL - Programmation
Marsh Posté le 09-12-2008 à 15:35:09
ici : http://forum.hardware.fr/hfr/Progr [...] 9707_1.htm
Même problème que toi. Il a eu des réponses.
Marsh Posté le 09-12-2008 à 16:38:58
getget a écrit : Bonjour, mon problème est le suivant :
mais ca ne marche pas |
C'est un compteur id _absence ?
Parce que je verrais bien un truc du genre
SELECT id_suivresemestre, id_seance, type
FROM matable
WHERE (id_absence IN
(SELECT MAX(id_absence)
FROM matable
GROUP BY id_suivresemestre, id_seance))
GROUP BY id_suivresemestre, id_seance, type
comme ça par seance et élève tu as la dernière absence enregistrée....si ton id_absence est bien un compteur
Marsh Posté le 10-12-2008 à 04:54:32
id_absence est une clé primaire auto incrémentée
Par contre, je dois pouvoir faire la même chose avec le dateDeclaration non ?
Je vais tester ta soluce
Le 2ème Group By est-il nécessaire ?
Marsh Posté le 10-12-2008 à 07:35:57
getget a écrit : |
cf le lien que j'ai donné
Marsh Posté le 10-12-2008 à 10:49:59
getget a écrit : id_absence est une clé primaire auto incrémentée |
Donc c'est bon, je suppose que tes évènements sont rentrés dans l'ordre, non ?
Si sur ta date_declaration tu ne gères pas l'heure précise, tu risques de te retrouver avec des doublons...
Les 2 group by sont nécessaires dans ma formule. Essaie de l'interpreter, tu comprendras.
Marsh Posté le 10-12-2008 à 10:51:53
kao98 a écrit : |
Je ne vois pas vraiment en quoi ton lien répond à sa question ?
Ptêt que j'ai pas compris sa question remarque
Marsh Posté le 10-12-2008 à 10:56:16
Le group by ! Dans un group by, il faut indiquer tous les champs du select !
Marsh Posté le 10-12-2008 à 11:00:30
kao98 a écrit : Le group by ! Dans un group by, il faut indiquer tous les champs du select ! |
J'avais même pas fait gaffe à son * avant le group by
Marsh Posté le 10-12-2008 à 23:41:55
kao98 a écrit : |
J'ai regardé ton lien, je n'y vois pas vraiment de rapport (et on peut, même si c'est mal, avec mysql >=4 )
Marsh Posté le 10-12-2008 à 23:44:28
chapi a écrit : |
Je teste ce soir
dateDeclaration est un champ datetime, peu de chance d'avoir un doublon
Marsh Posté le 11-12-2008 à 09:08:24
chapi a écrit : |
J'ai essayé d'interpréter ta requète, mais je ne comprends toujours pas l'intérêt du 2ème GROUP BY
Le 1er (SELECT MAX(id_absence) FROM matable GROUP BY id_suivresemestre, id_seance) permet d'obtenir l'id_absence le plus grand pour chaque regroupement de séance, utilisé dans l'autre requète SELECT id_suivresemestre, id_seance, type FROM matable WHERE (id_absence IN ...) GROUP BY id_suivresemestre, id_seance, type.
Puisque les données ont été regroupées par la 1ère et le resultat de cette requète utilisé dans le 2ème, je ne vois pas l'intérêtdu GROUP BY
Un
SELECT * FROM matable WHERE (idAbsence IN (SELECT MAX(idAbsence) FROM matable GROUP BY idSeanceVt, idSuivre_semestre) AND idSuivre_semestre=:idSuivre_semestre |
me renvoie le bon résultat si executé dans phpMyAdmin.
Marsh Posté le 11-12-2008 à 09:32:01
getget a écrit : |
T'as raison, il ne sert strictement à rien.
J'avais dû mettre un aggregat dans ma premiere version et oublié de virer le group by.
Sorry, la prochaine fois je me relirai
Marsh Posté le 11-12-2008 à 09:35:06
Pas grave, merci tout de même
Marsh Posté le 21-03-2009 à 01:40:36
Bonjour, aujourd'hui je rencontre un nouveau soucis avec cette requête, les performances s'écroulent alors qu'il y a a peine 100 enregistrements dans la table
J'ai un peu farfouillé sur le net sur les performances de GROUP BY mais je n'a trouvé que 2/3 propositions, dont la création d'une table temporaire ...auriez vous d'autres solutions ?
Marsh Posté le 21-03-2009 à 02:10:03
Certainement le IN qui plante les perf...! faut utiliser une jointure
Marsh Posté le 21-03-2009 à 02:14:55
remplacer :
SELECT *
FROM matable
WHERE (
idAbsence IN
(
SELECT MAX(idAbsence)
FROM matable
GROUP BY idSeanceVt, idSuivre_semestre
)
par :
SELECT *
FROM matable A inner join
(
SELECT MAX(idAbsence) as idAbsence
FROM matable
GROUP BY idSeanceVt, idSuivre_semestre
) as B on A.idAbsence = B.idAbsence
je ne pige pas le "AND idSuivre_semestre=:idSuivre_semestre", trop tard pour reflechir plus !
Marsh Posté le 21-03-2009 à 02:24:30
On peut joindre une table avec elle même ?
Marsh Posté le 21-03-2009 à 02:52:33
Ca marche (avec un gain x3)
Marsh Posté le 21-03-2009 à 10:01:55
getget a écrit : Ca marche (avec un gain x3) |
QQ regle d'or de la programmation SQL :
- eviter les IN
- NE JAMAIS UTILISER LES CURSEURS --> dans 99.9% un select est possible
- eviter les jointure sur des colonnes de type char/varchar
Marsh Posté le 21-03-2009 à 14:23:32
Merci bien !
Je vais essayer d'améliorer encore un peu le truc car le script met quand même 3s d'execution, c'est un poil longuet
Si je met une clause WHERE là ou il y a le GROUP BY, elle sera traitée avant ou après le regroupement ?
Marsh Posté le 21-03-2009 à 21:57:05
Evite le SELECT *
Ne récupère que les champs dont tu as besoin. Et si tu as besoin de tous les champs de la table, alors liste les tous.
Marsh Posté le 22-03-2009 à 01:18:51
getget a écrit : Merci bien ! |
humm... bizarre ta question...
Le regroupement se fait sur le jeu de résultat renvoyé, donc logiquement la clause "where" est jouée avant.
Marsh Posté le 26-03-2009 à 13:04:02
getget a écrit : Merci bien ! |
La clause WHERE s'exécute avant le regroupement.
Si tu veux rajouter un filtre sur le regroupement, il faut utiliser la clause "HAVING".
Par exemple : récupération des moyennes des salaires annuels par catégorie professionnelle supérieures à 30000€
Code :
|
Marsh Posté le 09-12-2008 à 14:40:02
Bonjour, mon problème est le suivant :
J'ai une table avec dedans des absences d'étudiants :
idAbsence idProfs idSuivre_semestre idSeanceVt dateDeclaration Type idCommente Commentaire
Pour un même cours (idSeanceVt), un même étudiant (idSuivre_semestre) peut avoir plusieurs enregistrements (par exemple il a été déclaré absent, puis finalement, absent justifié), bref.
Je voudrai faire une requete qui récupère toutes les absences d'un étudiant (idSuivre_semestre), les regroupe par séance (idSeanceVt) puis ne me garde que le dernier en date du regroupement (par séance donc).
Je pensais utiliser la clause "GROUP BY idSeanceVt", qui me regroupe bien les lignes par séance, mais je n'arrive pas à choisir quel enregistrement il doit me renvoyer (il me renvoie toujours le 1er par id)...
J'ai tenté
SELECT * FROM matable WHERE idSuivre_semestre=:idSuivre_Semestre GROUP BY idSeanceVt ORDER BY dateDeclaration DESC
mais ca ne marche pas
Merci d'avance !
Message édité par getget le 09-12-2008 à 14:41:30
---------------
Gamertag : Getget94 - PSN : Getget1980 - Nintendo Network : Getget1980 - Uplau : Getget1980