Requete Group by

Requete Group by - SQL/NoSQL - Programmation

Marsh Posté le 31-01-2005 à 15:08:23    

Bonjour,
 
Je developpe un forum en php, et je voudrais afficher les 10 derniers messages. Je fais donc la requete suivante :
 

Code :
  1. SELECT DISTINCT ForumPost.PostID,ForumPost.TopicID, ForumPost.Auteur, ForumPost.DateMAJ, ForumTopic.Titre
  2. FROM ForumPost, ForumTopic
  3. WHERE ForumTopic.TopicID=ForumPost.TopicID
  4. GROUP BY Titre
  5. ORDER BY ForumPost.DateMAJ
  6. DESC limit 0,10


 
J'obtiens bien la liste des 10 derniers enregistrements de la table ForumPost... le probleme c'est que je ne recupere pas le bon PostID quand SQL fait le regroupement: je recupere le PostID du post le plus ancien et non celui du plus recent ...
 
==> comment peut-on indiquer que lors du regroupement par titre, il doit prendre le PostID et l'Auteur du post le plus recent ??
 
merci d'avance !

Reply

Marsh Posté le 31-01-2005 à 15:08:23   

Reply

Marsh Posté le 31-01-2005 à 15:33:41    

Un "group by" sans fonction de regroupement ? Y'a une couille dans le potage là... ;) Vire cette close immédiatement :o
 
En plus, déjà que ton DISTINCT fait tout rammer, mais en plus un GROUP BY sur une chaîne de caractères, tu cherches à endormir l'utilisateur le temps que la page se charge, spa possible ;)


Message édité par Arjuna le 31-01-2005 à 15:34:33
Reply

Marsh Posté le 31-01-2005 à 15:53:07    

ok, mais alors je fais comment pour grouper mes posts ???
ca ne sert pas a ca group by ?

Reply

Marsh Posté le 31-01-2005 à 16:18:28    

Non, ça sert pas à ça.
 
GROUP BY s'utilise avec des fonctions d'agregation telles que :
 
MAX(), MIN(), AVG() par exemple.
 
Pour toi, le DISTINCT fait le travail.
Par contre, essaie de faire cette requête, qui sera infiniment plus rapide :
 

Code :
  1. SELECT Max(ForumPost.PostID), ForumTopic.TopicID, MAX(ForumPost.DateMAJ), ForumTopic.Titre
  2. FROM ForumPost, ForumTopic
  3. WHERE ForumTopic.TopicID=ForumPost.TopicID
  4. GROUP BY ForumTopic.TopicID, ForumTopic.Titre
  5. ORDER BY ForumPost.PostID DESC
  6. DESC limit 0,10


 
Ca doit retourner ce que tu veux, et ce sera incomparablement plus rapide (et autrement plus propre)
 
En fait, tu récupère la date maximale et le postid maximal pour chaque couple TopicID/Titre de topic.
Si tu ajoutes l'auteur directement dans cette requête, tu auras la même info, mais pour chaque triplet TopicID/Titre de Topic/Auteur, et c'est pas ce que tu veux.
 
Une fois le résultat obtenu, il te faudra donc refaire une requête pour récupérer l'auteur de chaque posts retournés, à moins que ta version de MySQL supporte les sous-requêtes. Dans ce cas, la requête est légèrement plus compliquée, mais tu peux tout faire en une seule requête. Je te laisse chercher ;)


Message édité par Arjuna le 31-01-2005 à 16:21:38
Reply

Marsh Posté le 31-01-2005 à 16:31:19    

P*tain c'etait plus simple que je ne pensais !!!
ta requete marche parfaitement ...en mettant un simplement MAX ...
arrrgggllllllll !!!!
merci, je vais en profiter pour repotasser le manuel SQL, je viens de mieux capter le fonctionnement des Group by ...
 
merci !!!

Reply

Marsh Posté le 21-02-2005 à 12:00:49    

mmm finalement cette requete ne marche pas : le tri final ORDER BY ForumPost.PostID DESC ne se fait pas (il est fait avant le group by)
 
Pour bien faire il faudrait avoir deux requetes imbriquées (l'une fait regroupe par PostID, l'autre presente les resultats par PostID decroissant) :

Code :
  1. SELECT PostID
  2. FROM (
  3. SELECT MAX(PostID) as postid
  4. FROM  ForumPost, ForumTopic
  5. WHERE ForumTopic.TopicID=ForumPost.TopicID 
  6. GROUP BY ForumTopic.Titre
  7. )
  8. ORDER BY PostID DESC limit 0,10


 
malheureusement mysql ne le digere pas. J'ai aussi essayé avec des AS mais ca ne marche pas non plus. J'avais pensé utiliser une table temporaire, mais ca risque d'allonger le temps de traitement.
 
QQu'un voit-il une solution plus smart ?

Reply

Marsh Posté le 21-02-2005 à 12:05:01    

Blackdalhia a écrit :

mmm finalement cette requete ne marche pas : le tri final ORDER BY ForumPost.PostID DESC ne se fait pas (il est fait avant le group by)
 
Pour bien faire il faudrait avoir deux requetes imbriquées (l'une fait regroupe par PostID, l'autre presente les resultats par PostID decroissant) :

Code :
  1. SELECT PostID
  2. FROM (
  3. SELECT MAX(PostID) as postid
  4. FROM  ForumPost, ForumTopic
  5. WHERE ForumTopic.TopicID=ForumPost.TopicID 
  6. GROUP BY ForumTopic.Titre
  7. )
  8. ORDER BY PostID DESC limit 0,10


 
malheureusement mysql ne le digere pas. J'ai aussi essayé avec des AS mais ca ne marche pas non plus. J'avais pensé utiliser une table temporaire, mais ca risque d'allonger le temps de traitement.
 
QQu'un voit-il une solution plus smart ?


 
Je suis un jeunot en SQL , mais une requete imbriquée, ce ne serait pas dans un
WHERE ... IN ( SELECT ... )  
 
??
J'ai jamais vu ca dans un from ;)

Reply

Marsh Posté le 21-02-2005 à 12:29:28    

ben j'ai essayé ca :

Code :
  1. SELECT *
  2. FROM  ForumPost, ForumTopic
  3. IN (
  4. SELECT MAX(PostID) as postid
  5. FROM  ForumPost, ForumTopic
  6. WHERE ForumTopic.TopicID=ForumPost.TopicID 
  7. GROUP BY ForumTopic.Titre
  8. )
  9. ORDER BY postid DESC limit 0,10


 
marche pô !

Reply

Marsh Posté le 21-02-2005 à 14:28:35    

déjà, vire ta foutue "*", c'estINTERDIT (par moi, et pas toute personne qui travaillera avec toi)
 
Sinon, dans ton sous-select, tu fais un group by sur un champ que tu ne retourne pas. Tu peux pas faire comme ça.
 
Deplus, le "FROM table1, table2 IN" de ta première requête ne veut rien dire.
 
Bref, y'a rien qui marche dans ta requête :D

Reply

Marsh Posté le 21-02-2005 à 14:38:34    

je sais bien que ca marche pô... ce sont des essais infructueux !!!!
Les * ca sera optimisé apres, j'essaie deja de trouver une requete qui marche
Quelle est la bonne méthode ????

Reply

Marsh Posté le 21-02-2005 à 14:38:34   

Reply

Marsh Posté le 21-02-2005 à 15:42:04    

select tmp.postid
from
(
   select max(forumpost.postid) as postid, forumtopic.titre
   from   forumpost, forumtopic
   where  forumpost.topicid = forumtopic.topicid
   group by forumtopic.titre
) tmp
order by tmp.postid desc limit 0, 10
 
ça me semble déjà mieu.
 
PS: j'espère que t'as une version de MySQL très récente, parceque c'est pas supporté depuis longtemps ce type de requêtes !

Reply

Marsh Posté le 21-02-2005 à 16:55:12    

ben je suis chez free, donc Mysql 4.0.22... ca marche pas ! arrrglllll !
comment on faisait avant ces versions ??

Reply

Marsh Posté le 21-02-2005 à 17:27:33    

tu passes à un autre sgbd chez un autre hébergeur ? :ange:

Reply

Marsh Posté le 21-02-2005 à 17:36:42    

ouai je vais pas tarder  :D  
mais bon en attendant je finalise mon site.
 
Merci en tout cas pour ton aide Arjuna !  :)  
 
bon je vais essayer de trouver une solution temporaire .... je vais me chercher un tube d'aspirine ...

Reply

Marsh Posté le 21-02-2005 à 18:01:31    

bah déjà, si ta requête se limite à ça, je sais pas pourquoi tu utilise une sous-requête...
 
select max(forumpost.postid) as postid, forumtopic.titre  
from   forumpost, forumtopic  
where  forumpost.topicid = forumtopic.topicid  
group by forumtopic.titre  
order 1 desc limit 0, 10

Reply

Marsh Posté le 21-02-2005 à 18:33:06    

oui c'est nickel, j'avais pas pensé à designer le numero de la colonne... là ca marche !!!!! J'ai plus qu'à recupérer le nom de l'auteur du dernier post (là il me donne celui du premier post...) mais c'est déjà super !!! merci !

Reply

Marsh Posté le 21-02-2005 à 19:03:26    

j'ai ajouté la requete pour l'auteur :

Code :
  1. $reqAuteur = "SELECT Auteur FROM ForumPost WHERE PostID=".$PostID;
  2. $Rauteur = mysql_db_query($bdd,$reqAuteur);
  3. while ($valauteur = mysql_fetch_array($Rauteur))
  4. { $Auteur = $valauteur["Auteur"]; }


 
mais du coup c'est super lent ... y a pas moyen d'optimiser ce truc ?
 
le probleme c'est qu'avec la requete GROUP BY j'ai aucun moyen de dire quelle valeur de Auteur je veux afficher....

Reply

Marsh Posté le 21-02-2005 à 19:20:44    

Ha ben là, non, et t'as en effet besoin de faire une sous-requête (bien plus complexe que celle que tu avais mis au départ)

Reply

Marsh Posté le 21-02-2005 à 20:08:16    

bon ben tant pis on verra ca dans la V2 ! Encore merci Arjuna !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed