2010-08-26 82 views
3

我有一个表articles,另一tags,第三个被称为article_tags。我想制作一个列出特定标签的所有文章的页面。获取所有文章与他们的标签GROUP_CONCAT字段

我的查询看起来是这样的:

SELECT headline, GROUP_CONCAT(tags.tag_name) AS all_tags FROM articles
LEFT JOIN articles_tags ON articles.article_id = articles_tags.article_id
LEFT JOIN tags ON articles_tags.tag_id = tags.tag_id
WHERE tags.tag_name = 'japan'
GROUP BY articles.article_id

所有返回的文章只有japan作为标记,即使有问题的文章有几个标签。

这显然与WHERE条款有关,但我无法弄清楚如何在这里做我想做的事情 - 理想情况下,我最终会得到一个像japan,china,korea这样的列表。这是子查询的地方吗?可以做一个SQL大师建议。

谢谢, 马特

+0

在您的查询中,您引用了tags表中的三个不同列:'tags.tag_id','tags.tag_name'和'tag ='japan''。这是一个错误吗?你可以发布你的表格定义来帮助澄清这一点吗? – 2010-08-26 20:24:31

+0

Hi Mark - 是的,oops - 'tag ='japan'应该读为'tag_name ='japan' - 为了这个例子我简化了表格定义。我只是在下面尝试你的代码,所以看看这个空间。 – 2010-08-26 20:26:37

回答

3

有可以使用至少两种方法。一种方法是两次加入表格。另一个你指出的是使用子查询。为了简单易读,我可能会在这里与子查询一起。生成的查询会是这个样子:

SELECT 
    headline, 
    GROUP_CONCAT(tags.tag_name) AS all_tags 
FROM articles 
JOIN articles_tags ON articles.article_id = articles_tags.article_id 
JOIN tags ON articles_tags.tag_id = tags.tag_id 
WHERE articles.article_id IN (
    SELECT articles.article_id 
    FROM articles 
    JOIN articles_tags ON articles.article_id = articles_tags.article_id 
    JOIN tags ON articles_tags.tag_id = tags.tag_id 
    WHERE tags.tag_name = 'japan' 
) 
GROUP BY articles.article_id 

而这里的使用方法更联接:

SELECT 
    a.headline, 
    GROUP_CONCAT(t2.tag_name) AS all_tags 
FROM articles a 
JOIN articles_tags at1 ON a.article_id = at1.article_id 
JOIN tags t1 ON at1.tag_id = t1.tag_id AND t1.tag_name = 'tag1' 
JOIN articles_tags at2 ON a.article_id = at2.article_id 
JOIN tags t2 ON at2.tag_id = t2.tag_id 
GROUP BY a.article_id; 
+0

这个工程,谢谢 - 但它花了一分钟跑!嗯。可能需要一些更好的索引... – 2010-08-26 20:28:29

+0

@Matt安德鲁斯:是的,这肯定需要索引,否则子查询将运行多次。您也可以尝试使用连接的方法。 – 2010-08-26 20:33:43

+0

@Matt Andrews:我已经更新了我的答案,包括使用连接的方法。 – 2010-08-26 20:42:34

2

使用EXISTS:

SELECT a.headline, 
      GROUP_CONCAT(t.tag_name) AS all_tags 
    FROM ARTICLES a 
LEFT JOIN ARTICLES_TAGS at ON at.article_id = a.article_id 
LEFT JOIN TAGS t ON t.tag_id = at.tag_id 
    WHERE EXISTS(SELECT NULL 
        FROM ARTICLES x 
        JOIN ARTICLE_TAGS y ON y.article_id = x.article_id 
        JOIN TAGS z ON z.tag_id = y.tag_id 
           AND z.tag_name = 'japan' 
        WHERE x.article_id = a.article_id) 
GROUP BY a.article_id 

无需使用LEFT在子查询的JOIN如果您只对与“japan”标签相关的内容感兴趣。

+0

我在'on clause'中得到了“Unknown column'x.tag_id'”查询。 – 2010-08-26 20:40:17

+0

@Mark Byers:Thx,已更正。 – 2010-08-26 20:43:42

+0

即使在更新几个外键和索引后,这也会更快(0.2秒)。尽管试图马克的其他建议。 – 2010-08-26 20:47:00

相关问题