Problème d'ordre avec LEFT JOIN et GROUP BY

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Problème d'ordre avec LEFT JOIN et GROUP BY

par furiouslol » 23 sept. 2008, 13:41

En fait dans ce cas la le max agit conjointement avec le Group by

Sinon pour le LEFT JOIN, c'est une jointure non stricte ... Je ne suis pas expert mais tu peux l'utiliser quand tu pense que l'existence d'enregistrement de cette table n'est pas obligatoire par rapport a ta table principale ...

Ici si tu pouvais avoir un message anonyme, sans membre donc, le LEFT JOIN aurait été adéquat

Sinon la syntaxe JOIN tout court est (ou était) équivalente a la syntaxe basique de jointure :

Code : Tout sélectionner

SELECT * FROM a, b WHERE a.ID=b.ID
Équivaut a

Code : Tout sélectionner

SELECT * FROM a JOIN b ON a.ID=b.ID
BIen que la deuxième syntaxe soit encouragée, je crois pour des raisons de portabilité sur toute les bases (syntaxe plus universelle si tu veux)

Enfin peut etre qu'un spécialiste pourra nous éclairer la dessus :)

par supercanard » 23 sept. 2008, 01:06

Bonsoir, ou bonjour plutot ;)

Merci de ton aide, le max(post.date) débloque tout.

Je n'ai pas encore bien compris la différence entre JOIN et LEFT JOIN mais en tous cas il y a obligatoirement un message pour un topic. Le terme réponse n'était pas approprié puisque lorsque l'on créé un topic on à obligatoirement un premier message, mais je le considère au même rang qu'une réponse car c'est déjà assez compliqué comme ça.

J'ai quand même changé id_post en max(post.date) car j'avais besoin de récupérer l'id du tout dernier pour mon système d'ancre HTML

En tous cas merci beaucoup car depuis hier j'étais complètement bloqué et je n'aurais pas pensé au coup du max car je ne connaissais pas =)

par furiouslol » 23 sept. 2008, 00:33

Salut

Déja il me semble que tu as beaucoup de LEFT JOIN

- Pour chaque topic, tu as obligatoirement un membre => le LEFT JOIN est inutile
- Ensuite, est ce que tu créé un POST pour chauqe TOPIC ? Si ce n'est pas le cas, tu va te retrouver a chercher une date qui n'existe pas, dans le cas d'un TOPIC auquel personne n'a répondu. Si c'est le cas par contre ton LEFT JOIN est inutile aussi :)

Dans le cas ou un POST est créé pour chaque TOPIC créé, je dirais :

Code : Tout sélectionner

SELECT topic . * , pseudo, max(post.date) AS lastReply, post.id_post FROM topic JOIN membre ON membre.id_membre = topic.id_membre JOIN post ON post.id_topic = topic.id_topic GROUP BY topic.id_topic

Problème d'ordre avec LEFT JOIN et GROUP BY

par supercanard » 21 sept. 2008, 23:11

Bonsoir,

Je ne sais pas comment je vais expliquer ça, mais on va essayer :D
En gros je suis en train de faire un forum. Pour lister les topics j'ai besoin de récupérer le sujet, la date de création, l'auteur et la date du dernier message. Cette liste doit être classé par dâte de message.
Le tout avec 3 tables dont voici la structure :

Code : Tout sélectionner

CREATE TABLE IF NOT EXISTS `membre` ( `id_membre` int(11) NOT NULL auto_increment, `email` varchar(200) collate utf8_bin NOT NULL, `pseudo` varchar(200) collate utf8_bin NOT NULL, `pwd` varchar(10) collate utf8_bin NOT NULL, `admin` tinyint(1) NOT NULL, PRIMARY KEY (`id_membre`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; CREATE TABLE IF NOT EXISTS `post` ( `id_post` int(11) NOT NULL auto_increment, `id_topic` int(11) NOT NULL, `id_membre` int(11) NOT NULL, `date` datetime NOT NULL, `message` text collate utf8_bin NOT NULL, PRIMARY KEY (`id_post`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; CREATE TABLE IF NOT EXISTS `topic` ( `id_topic` int(11) NOT NULL auto_increment, `id_membre` int(11) NOT NULL, `nom` varchar(200) collate utf8_bin NOT NULL, `date` datetime NOT NULL, PRIMARY KEY (`id_topic`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
Alors étant un novice dans les jointures voici ce que j'ai fait :
SELECT topic . * , pseudo, post.date AS lastReply, post.id_post
FROM topic
LEFT JOIN membre ON membre.id_membre = topic.id_membre
LEFT JOIN post ON post.id_topic = topic.id_topic
GROUP BY topic.id_topic
ORDER BY post.date DESC
C'est là ou ça se corse pour expliquer le problème. En gros en faisant un test je me rend compte que la dâte de dernière réponse ( lastReply ) n'est pas la bonne. Du coup l'ordre est mauvais.
Si j'enlève group by le problème disparait mais je me retrouve avec une même ligne répétée à chaque fois qu'il y a un message, ce n'est donc pas le but.

J'espère que vosu me suivez, ce n'est pas évident à expliquer comme ça ;)