2010-04-04 5 views
2

je les tableaux suivants:MySQL GROUP BY avec trois tables

posts (post_id, content, etc) 

comments (comment_id, post_id, content, etc) 

posts_categories (post_category_id, post_id, category_id) 

et cette requête:

SELECT `p`.* 
    , COUNT(comments.comment_id) AS cmts 
    , posts_categories.* 
    , comments.* 
    FROM `posts` AS `p` 
    LEFT JOIN `posts_categories` 
    ON `p`.post_id = `posts_categories`.post_id 
    LEFT JOIN `comments` 
    ON `p`.post_id = `comments`.post_id 
GROUP BY `p`.`post_id` 

Il y a trois commentaires sur post_id = 1 et quatre au total. Dans posts_categories, il y a deux lignes, toutes deux affectées à post_id = 1. J'ai quatre rangées dans les messages. Mais si j'interroge l'instruction ci-dessus, j'obtiens un résultat de 0 pour COUNT(comments.comment_id) à post_id = 1. Comment est-ce possible? Je suppose que l'erreur est quelque part dans la clause GROUP BY mais je ne peux pas savoir où.

Des suggestions?

Répondre

1

En première approximation essayer

SELECT `p`.* 
    , COUNT(DISTINCT comments.comment_id) AS cmts 
    , posts_categories.* 
    , comments.* 
    FROM `posts` AS `p` 
    LEFT JOIN `posts_categories` 
    ON `p`.post_id = `posts_categories`.post_id 
    LEFT JOIN `comments` 
    ON `p`.post_id = `comments`.post_id 
GROUP BY `p`.`post_id` 

EDIT:

Cependant, COUNT (champ DISTINCT) est plus cher que COUNT (champ) et doit être évité si pas nécessaire. Puisque vous ne l'attendez pas, je dirais que dans votre cas ce n'est pas nécessaire.

Votre problème provient du fait que vos jointures renvoient 3 (commentaires) x 2 (catégories) = 6 lignes. Je ne sais pas ce que vous utilisez les résultats, mais peut-être que vous devriez repenser votre requête.

0

Je suppose que vous avez plus d'une catégorie impliquée!

Est-ce que

SELECT P.post_id 
    , PC.post_category_id 
    , COUNT(C.comment_id) AS cmts 
    FROM `posts` AS P 
    LEFT JOIN `posts_categories` as PC 
    ON `p`.post_id = `posts_categories`.post_id 
    LEFT JOIN `comments` as C 
    ON P.post_id = C.post_id 
GROUP BY P.post_id, PC.post_category_id 

vous donne un résultat 'compréhensible'?

BTW Vous devriez avoir tous les champs du clause GROUP BY qui ne sont pas agrégées ...

+0

Dans mysql, il n'est pas nécessaire de lister tous les champs dans GROUP BY, mais cela entraîne les problèmes décrits ci-dessus avec le nombre – Unreason

+0

Qu'en est-il de l'attribut post_category_id? Avez-vous essayé la requête. Si vous ne comprenez pas ce que je veux dire, regardez la réponse de @Adam Bernier. – lexu

+0

Ne fonctionne pas pour moi, j'ai omis GROUP_CONCAT pour faciliter la recherche. Merci quand même – Psaniko

0

Vous obtenez six (6) commentaires parce que votre resultset ressemble à ceci:
(note les deux groupes de trois rangées chacune, l'une pour chaque catégorie abrégé poste pcat *)

 
post_id cmts post_cat comments 
1  6  pcat1  comment text... 
1  6  pcat1  comment text... 
1  6  pcat1  comment text... 
1  6  pcat2  comment text... 
1  6  pcat2  comment text... 
1  6  pcat2  comment text... 

Vous pouvez faire quelque chose comme ceci:

SELECT `p`.post_id, 
     COUNT(comments.comment_id) AS cmts, 
     COUNT(posts_categories.) AS categories 
    FROM `posts` AS `p` 
     LEFT JOIN `posts_categories` 
     ON `p`.post_id = `posts_categories`.post_id 
     LEFT JOIN `comments` 
     ON `p`.post_id = `comments`.post_id 
GROUP BY `p`.`post_id` 
+0

Désolé mais j'ai toujours 6 commentaires ce qui est définitivement faux. Je n'ai peut-être pas assez expliqué ce que je voulais obtenir, merci quand même. – Psaniko