Page 1 sur 1
2 requetes en une : UNION et COUNT
Posté : 30 sept. 2008, 00:00
par supercanard
Bonsoir,
Voilà après avoir retourner dans tous les sens le peu de doc que j'ai pu trouver à propos d'UNION, essayé des syntaxes différentes je vient chercher vos éclaircissements.
Je cherche tout simplement à faire un count sur 2 tables dans une seule requête mais ça n'a pas l'air aussi simple que ça en fait
SELECT COUNT( id_post ) AS nbPost
FROM post
WHERE id_membre =1
UNION SELECT COUNT( id_topic ) AS nbTopic
FROM topic
WHERE id_membre =1
Le résultat me retourne 2 valeurs complètement farfelues pour nbPost ( pourquoi 2 déjà c'est une bonne question) et rien du tout pour nbTopic.
Dans mon code php par contre j'ai une erreur : Notice: Undefined index: nbTopic in... etc
Code : Tout sélectionner
CREATE TABLE `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 NOT NULL,
PRIMARY KEY (`id_post`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=51 ;
CREATE TABLE `topic` (
`id_topic` int(11) NOT NULL auto_increment,
`id_membre` int(11) NOT NULL,
`nom` varchar(250) NOT NULL,
`date` datetime NOT NULL,
`postit` tinyint(1) NOT NULL,
`test` tinyint(1) NOT NULL,
PRIMARY KEY (`id_topic`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ;
Posté : 30 sept. 2008, 01:18
par furiouslol
Salut en fait il me semble que les SELECT des requêtes qui composent ton UNION doivent contenir les mêmes sorties, donc dans ton cas il faudrait ruser ... Je rajoute en plus des parenthèses et des alias pour etre sur
Code : Tout sélectionner
(SELECT COUNT( p.id_post ) AS nbPost, 0 AS nbTopic
FROM post p
WHERE p.id_membre =1)
UNION
(SELECT 0 AS nbPost, COUNT( t.id_topic ) AS nbTopic
FROM topic t
WHERE t.id_membre =1);
Ça te donnera un résultat du genre
Bon ceci dit dans ton cas c'est un peu tricky de faire appel a un UNION alors que tes ensembles ne s'entrecoupent pas, il te suffit de faire un JOIN sur ton id_member
Code : Tout sélectionner
SELECT COUNT( p.id_post ) AS nbPost, COUNT( t.id_topic ) AS nbTopic
FROM post p, topic t
WHERE p.id_membre = t.id_membre
AND t.id_membre =1Ceci évidement si tu cherche bine a compter a partir du même user
Posté : 30 sept. 2008, 10:03
par supercanard
Salut
Merci de ta réponse
Par contre absolument rien compris à la requête avec union qui me sort effectivement 2 valeurs pour chaque colonnes mais il n'en faudrait qu'une. 2 en tout.
Pour la deuxième requête effectivement ce serrait plus logique mais le résultat est assez byzar :
125O topics, 1250 posts
ALors qu'en ai à peine 100 dans chaque tables
Posté : 30 sept. 2008, 12:09
par furiouslol
Oui euh milles excuses, la deuxième requête est complètement fausse
La première est pas mal, normalement le résultat est juste, bien que présenté en deux ligne, ça reste facilement utilisable en php, j'vais voir si je trouve pas une amélioration tout de même
Posté : 30 sept. 2008, 13:17
par furiouslol
Tiens essaye donc celle la sur ta base :
Code : Tout sélectionner
SELECT COUNT(DISTINCT(t.id_topic)) AS nbTopic , COUNT(p.id_post) AS nbPost
FROM post p, topic t
WHERE p.id_membre = t.id_membre
AND t.id_topic = p.id_topic
AND t.id_membre=1
Posté : 30 sept. 2008, 14:19
par supercanard
C'est exactement ça, en tous cas ça marche mais par contre je suis largué
Je comprend pas du tout pourquoi on fait un distinct sur t.id_topic

Posté : 30 sept. 2008, 16:46
par furiouslol
En fait j'ai procédé par étape et sur un petit échantillon, ça aide a la réflexion, j'ai commencé par
Code : Tout sélectionner
SELECT *
FROM post p, topic t
WHERE p.id_membre = t.id_membre
AND t.id_membre=1
Dans mon exemple (2 topics avec 3 posts) ça me donnait 6 lignes de résultats, j'ai donc rajouté
, car les autres lignes n'avaient aucun sens
Il me restait donc trois lignes, correspondant au tableau des posts, avec leurs topics associé
Une fois ce résultat obtenu tu vois aisément que tu peux compter directement les posts, mais qu'il te faut compter les topics uniques, d'où le DISTINCT
Posté : 02 oct. 2008, 00:36
par supercanard
Merci c'est bien mieux avec des explications =)
Posté : 03 oct. 2008, 20:38
par supercanard
Je réouvre le topic.
En fait il y à un petit problème...
La requête ne marche que si l'on à créé un topic. Mais si l'on à seulement répondu à un post, l'id membre n'apparaissant donc pas dans la table topic, le compteur reste à zéro car :
WHERE p.id_membre = t.id_membre
J'ai donc pensé à ça mais ça ne change rien à priori :
SELECT COUNT(DISTINCT(t.id_topic)) AS nbTopic , COUNT(p.id_post) AS nbPost
FROM post p, topic t
WHERE p.id_membre = $idMembre
AND t.id_topic = p.id_topic
AND t.id_membre= $idMembre
Posté : 04 oct. 2008, 01:05
par sadeq
Tu dois faire dans ce cas une jointure externe qui te permettra d'inclure les posts même si aucun topic n'est joint.
Code : Tout sélectionner
SELECT COUNT(DISTINCT(t.id_topic)) AS nbTopic , COUNT(p.id_post) AS nbPost
FROM post p LEFT JOIN topic t ON (p.id_membre = t.id_membre AND t.id_topic = p.id_topic)
WHERE t.id_membre=$idMembre
LEFT JOIN = Jointure externe à gauche. La table de gauche étant ici "post". La requête retournera alors tous les enregistrements de "post" (qui bien sûr correspondent à $idMembre) et seulement ceux de table "topic" qui respectent le critère de jointure.