我在这个场景中使用了三个表: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条)相同。
答案 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!