如何根据包含两个表的标签查询相关文章?

时间:2015-06-17 06:33:07

标签: mysql

我在这个场景中使用了三个表:articles,tags和article_tags。为了管理标签,我使用了一个单独的标签表。 article_tags表将文章链接到标签。所以表格看起来像这样:

articles:
|-------------------|
|--article_id(int)--|
|-------------------|

tags
|-------------------|
|---tag_id(int)-----|
|--keyword(varchar)-|
|-------------------|

article_tags
|-------------------|
|-article_tag_id(int)|
|-article_id(int)---|
|----tag_id(int)----|
|-------------------|

所以我想在正在查看的文章中获取具有最常见标签的文章,并按匹配顺序排序结果。我该怎么做?

这是我在仅使用一个表格进行标记时使用的查询。

SELECT t2.article_id, count(t2.keyword) AS matches,
                a.article_id AS related_id
            FROM article_tags t1
            JOIN article_tags t2 ON (t1.keyword = t2.keyword AND t1.article_id != t2.article_id)
            JOIN articles a on (t2.article_id = a.article_id)
            WHERE t1.article_id = ".$article_id."
            GROUP BY t2.article_id
            ORDER BY matches DESC
            LIMIT 5

考虑this架构......如果正在查看文章ID#1,则第2条和第3条都将包含在结果中,但是,第3条将在第2条之前显示,因为第2条中有更多标签与正在查看的文章(第1条)相同。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您的查询应该看起来像这样

SELECT t2.article_id, COUNT(t2.tag_id) AS matches
FROM (SELECT article_id, tag_id
      FROM article_tags
      WHERE article_id = 1) t1 
INNER JOIN (SELECT article_id, tag_id
            FROM article_tags
            WHERE article_id != 1) t2
ON t1.tag_id = t2.tag_id
GROUP BY t2.article_id
ORDER BY matches DESC
LIMIT 5;

第一个子查询t1选择article_id(我认为这不是必须的,你只能选择tag_id)并且文章的tag_id被查看...

第二个子查询t2为所有其他文章选择article_id和tag_id。

我们基于来自两个子查询的tag_id进行简单的INNER JOIN(这将排除t2中与第一个表中的tag_id不匹配的所有tag_id)。

在此之后,我们只需对计数标签进行分组和订购......

以下是SQL Fiddle,了解它是如何运作的。

GL!