MySQL GROUP BY有三个表

时间:2010-04-04 17:37:49

标签: mysql count group-by

我有以下表格:

posts (post_id, content, etc) 

comments (comment_id, post_id, content, etc)

posts_categories (post_category_id, post_id, category_id)

和这个查询:

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`

对post_id = 1有三条评论,总共有四条评论。在posts_categories中有两行,都分配给post_id = 1。我在帖子中有四行。

但是如果我查询上面的语句,我会在post_id = 1时得到COUNT(comments.comment_id)的结果为6。这怎么可能?我猜这个错误是在GROUP BY子句的某个地方,但我无法弄清楚在哪里。

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

作为第一个近似尝试

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`

编辑:

但是,COUNT(DISTINCT字段)比COUNT(字段)更昂贵,如果没有必要,应该避免。既然你没有想到它,我会说在你的情况下没有必要。

您的问题来自于您的联接返回3(注释)x 2(类别)= 6行。我不知道你使用了什么结果,但也许你应该重新考虑你的查询。

答案 1 :(得分:0)

我的猜测是你涉及多个类别!

确实

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

给你一个“可以理解的”结果?

BTW 您应该在GROUP BY子句中包含未聚合的所有字段...

答案 2 :(得分:0)

您收到六(6)条评论,因为您的结果集看起来像这样:
(注意两组各有三行;每个帖子类别一个 - 缩写为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...

你可以这样做:

  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`