MySQL加入3个表并计算另一个表

时间:2013-02-23 22:33:34

标签: mysql sql

我正在创建一篇博文,其中有一篇文章可以包含标签和评论。我想尝试获得正确的SQL以获得一个查询。 我有4张桌子:

article
+------------+-----------------+------------+
| article_id | title           | photo      |
+------------+-----------------+------------+
|          1 | This is a test  | image1.jpg |
|          2 | Another Article | image2.jpg |
+------------+-----------------+------------+


article_tag
+------------+--------+ 
| article_id | tag_id |
+------------+--------+
|          1 |      1 | 
|          1 |      2 | 
|          2 |      2 |
+------------+--------+

tags
+--------+------+ 
| tag_id | name |
+--------+------+ 
|      1 | tag1 |
|      2 | tag2 |
+--------+------+

comment
+------+---------+------------+
| name | message | article_id |
+------+---------+------------+
|    1 | hello   |          1 |
|    2 | a       |          2 |
+------+---------+------------+

我正试图解决这个问题:

+------------+----------------+------------+---------+----------+
| article_id | title          | photo      | tag_ids | comments |
+------------+----------------+------------+---------+----------+
|          1 | This is a test | image1.jpg | 1,2     |        1 |
+------------+----------------+------------+---------+----------+

这是我到目前为止所做的:

SELECT a.article_id, a.title, a.photo, a.date, a.description_long, a.author, GROUP_CONCAT(tag_id) as `tag_ids`, COUNT(c.comment_id) as comments
FROM article as a
JOIN article_tag as at
ON a.article_id = at.article_id
LEFT JOIN comment as c
ON a.article_id = c.article_id
WHERE a.article_id = 1

但是我的评论是2而不是1? 谢谢 PS如果有人知道一种方法,以便我可以将tag_ids从1,2更改为tag1,那么tag2将是惊人的: - )

2 个答案:

答案 0 :(得分:1)

标签和评论是独立的。因此,如果您有三个标记和两个注释,则组合中将获得6行。

在MySQL中修复此查询的最简单方法是在select中执行group by并使用distinct:

SELECT a.article_id, a.title, a.photo, a.date, a.description_long, a.author,
       GROUP_CONCAT(distinct tag_id) as `tag_ids`, COUNT(distinct c.comment_id) as comments
FROM article a JOIN
     article_tag as at
     ON a.article_id = at.article_id LEFT JOIN
     comment c
     ON a.article_id = c.article_id
WHERE a.article_id = 1
group by a.article_id

我会说,修复查询的“正确”方法是修复连接。这使用from

中的子查询
from . . .
     (select article_id, group_concat(tag_id) as tags
      from tags
      group by article_id
     ) at
     . . .
     (select article_id, count(*) as numComments
      from comments
      group by article_id
     ) c
     . . .

答案 1 :(得分:0)

这是因为有超过1个标签,因此生成了2行。

尝试COUNT(DISTINCT c.comment_id)。这只会计算不同的注释ID,因此重复的注释ID不会被计算两次。

要获取标记名称,请使用tags表格进行左连接。然后是GROUP_CONCAT,其名称为column,而不是tag_id列。

这是它应该是什么:

SELECT a.article_id, a.title, a.photo, a.date, a.description_long, a.author, GROUP_CONCAT(d.name) AS `tag_names`, COUNT( DISTINCT c.comment_id ) AS comments
FROM article as a
JOIN article_tag as at
ON a.article_id = at.article_id
LEFT JOIN comment as c
ON a.article_id = c.article_id
LEFT JOIN tags d ON at.tag_id = d.tag_id
WHERE a.article_id = 1