Select avec count() sur 3 tables

Eléphanteau du PHP | 13 Messages

12 oct. 2006, 16:08

Bonjours à tous !

Voilà, j'ai 3 tables pour un forum. Résumons ça :
- f_section (S dans la requète), avec id
- f_discut (D dans la requète), avec id et id_section (pour faire simple)
- f_reponse (R dans la requète), avec id et id_discut (toujours pour faire simple)

Le but de ma requète est de lister mes sections avec les nb de discutions et le nb de réponses.

Actuellement, j'ai un jeu d'essai qui devrait me donner (où : id section, nb discut, nb reponse) :
1 | 2 | 4
2 | 0 | 0
3 | 1 | 2
4 | 0 | 0

Voici la requète incriminée :

Code : Tout sélectionner

SELECT S.id, COUNT(D.id) AS nbdiscut, COUNT(R.id) AS nbreponse FROM f_section S LEFT JOIN f_discut D ON S.id = D.id_section LEFT JOIN f_reponse R ON D.id = R.id_discut GROUP BY S.id
Et ça me retourne :
1 | 4 | 4
2 | 0 | 0
3 | 2 | 2
4 | 0 | 0

En sachant que le problème est apparu quand j'ai ajouté ma 3ème table dans la requète... avant mon COUNT() sur mes discutions passés bien :cry:

Si vous avez une idée avant qu'une calvitie me frappe ce serait sympas.
Par avance, merci.
Rob.

Mammouth du PHP | 19672 Messages

12 oct. 2006, 18:50

Là où se trouve l'erreur, c'est que le second JOIN ne s'effectue pas sur les bonnes tables : la table f_reponse devrait être joint à la table f_discut et non avec f_section. DOnc la correction logique serait d'inverser les deux premières tables. Ce qui devrait ressembler à ça :

Code : Tout sélectionner

SELECT S.id, COUNT(D.id) AS nbdiscut, COUNT(R.id) AS nbreponse FROM f_discut AS D LEFT JOIN f_section AS S ON D.id_section = S.id LEFT JOIN f_reponse AS R ON D.id = R.id_discut GROUP BY S.id;
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 13 Messages

12 oct. 2006, 23:19

Oké mici 8)

Je test ça demain à la première heure et je commente tout ça voir.

Mais, c'est "bizarre", j'arrive pas à piger, il me semblé que c'étais bon ce que j'avais fais.
J'voyais bien un shéma genre section > discut* > reponse. Bref ! Je regarderais à la fraiche. Merci.

* que d'ailleur j'viens d'apprendre que discution c'est discussion... punaise, ça craint, tous mes forums précédement ecrit j'ai "discution"... j'ai m'convertir tout ça en sujet :wink:

Eléphanteau du PHP | 13 Messages

16 oct. 2006, 10:49

Alors !! Apparement, rien n'y fait pour l'instant.

J'ai beau organiser "différement" les RIGHT JOIN entre mes tables, ça change rien :cry:
Dés que je place la jointure de ma table f_reponse, ça me retourne un résultat comme s'il fesait un regroupement sur f_discut.

Je vous lache, en cas, mon jeu d'essai voir si vous pouvez trouver quelque chose :

Code : Tout sélectionner

CREATE TABLE `f_section` ( `id` int(11) NOT NULL auto_increment, `libsection` varchar(40) NOT NULL default '', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ; INSERT INTO `f_section` VALUES (1, 'Section bla-bla'); INSERT INTO `f_section` VALUES (2, 'Section youpi'); INSERT INTO `f_section` VALUES (3, 'Section youpla'); INSERT INTO `f_section` VALUES (4, 'Section uhuhuuuu'); CREATE TABLE `f_discut` ( `id` int(11) NOT NULL auto_increment, `id_section` int(11) NOT NULL default '0', `libdiscut` varchar(50) NOT NULL default '', `nbvue` int(11) NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; INSERT INTO `f_discut` VALUES (1, 1, 'Oui heu', 0); INSERT INTO `f_discut` VALUES (2, 1, 'lalala', 0); INSERT INTO `f_discut` VALUES (3, 3, 'A nooooooon', 0); CREATE TABLE `f_reponse` ( `id` int(11) NOT NULL auto_increment, `id_discut` int(11) NOT NULL default '0', `pseudo` varchar(30) NOT NULL default '0', `contenu` text NOT NULL, `dateheure` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ; INSERT INTO `f_reponse` VALUES (1, 1, 'MouchMuch', 'texte :)', '2006-10-09 18:53:02'); INSERT INTO `f_reponse` VALUES (2, 2, 'Jean Claude Vanglade', 'texte encore', '2006-10-09 19:23:45'); INSERT INTO `f_reponse` VALUES (3, 1, 'George', 'texte', '2006-10-09 20:18:52'); INSERT INTO `f_reponse` VALUES (4, 3, 'Zoubi la moche', 'texte texte', '2006-10-10 08:02:23'); INSERT INTO `f_reponse` VALUES (5, 1, 'Lololo lolo', 'PO POLOPOPO POLO POLO POPO', '0000-00-00 00:00:00'); INSERT INTO `f_reponse` VALUES (7, 3, 'uuuuuuurf', 'texte texte texte', '2006-10-11 12:03:41');

Par avance, merci.

Eléphanteau du PHP | 13 Messages

17 oct. 2006, 13:23

Bon... aprés moultes essais, j'ai pris la décision d'utiliser une requête imbriquée.

Voilà le rendu final :

Code : Tout sélectionner

SELECT S.id, COUNT(R.id) AS nbreponse, (SELECT COUNT(id) FROM f_discut WHERE f_discut.id_section=S.id) AS nbdiscut FROM f_discut AS D LEFT JOIN f_section AS S ON D.id_section = S.id LEFT JOIN f_reponse AS R ON D.id = R.id_discut GROUP BY S.id;
En cas, si vous voyez plus simple, n'hésitez pas à lacher le bouzin :twisted: