2013-02-23 63 views
1

我正在创建一篇文章,该文章可以包含标签和评论。我想尝试并获得正确的SQL来获得一个查询。 我有4个表:MySQL加入3个表并计算另一个

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将会非常惊人:-)

+0

有没有所谓的'comment_id'在你的评语表列... – Terry 2013-02-23 22:39:01

+0

数不同,它返回因为与商品标签中加入 – jazzytomato 2013-02-23 22:41:57

+0

对不起忘了包括2号线在问题中。但我有一个 – supajason 2013-02-24 18:01:44

回答

0

这是由于这样的事实,存在多于1个标记,所以产生2行。

试试COUNT(DISTINCT c.comment_id)。这将只计算不同的评论ID,所以重复的不会被计算两次。

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

下面是它应该是什么:

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 
+0

顺便说一句,如果你想一次有多个文章的这个信息,用GROUP BY替换WHERE子句a.article_id – 2013-02-23 23:10:35

+0

谢谢你的工作。我不得不DISTINCT GROUP_CONCAT(d.name) 令人惊叹:-) – supajason 2013-02-24 18:03:25

1

标签和注释是独立的。所以,如果你有三个标签和两个评论,你会在组合中获得6行。

解决在MySQL此查询的最简单的方法是做一个组,在选择使用不同的:

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 
    . . .