因此,我有一个数据库,其中有一个名为article的表,还有一个名为文章标签的表。当用户查看一篇文章时,我想查询最多五篇标签与正在查看的文章相似的文章。下面是我的两个表:
CREATE TABLE `articles` (
`article_id` int(15) NOT NULL AUTO_INCREMENT,
`parent_id` int(15) NOT NULL,
`author_id` int(15) NOT NULL,
`title` text NOT NULL,
`content` text NOT NULL,
`date_posted` text NOT NULL,
`views` int(15) NOT NULL,
`preview` text NOT NULL,
`status` tinyint(1) NOT NULL,
`modified_date` text NOT NULL,
PRIMARY KEY (`article_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `article_tags` (
`tag_id` int(15) NOT NULL AUTO_INCREMENT,
`article_id` int(15) NOT NULL,
`keyword` varchar(250) NOT NULL,
PRIMARY KEY (`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
我试着编写我自己的查询,但它们似乎从来都不起作用。我想在查询中使用joins,而不是使用CSV和LIKE。下面是我到目前为止得到的查询:
SELECT A2.article_id, count(A2.article_id) AS matches
FROM article_tags AS A1 JOIN article_tags ON (A1.keyword = A2.keyword AND 1.article_id != A2.article_id)
JOIN articles ON (A2.article_id = A.article_id) AS A
WHERE A1.article_id = 1
GROUP BY A2.article_id
ORDER BY matches DESC
LIMIT 5"这是我更新的查询:
$query = "
SELECT t2.article_id, count(t2.keyword) AS matches
FROM article_tags t1
JOIN article_tags t2 ON (t1.keyword = t2.keyword AND t1.article_id != t2.article_id)
WHERE t1.article_id = ".$article_id."
GROUP BY t2.article_id
ORDER BY matches DESC
LIMIT 5";
这是使用var_dump转储数组的结果
array
0 =>
array
'article_id' => string '2' (length=1)
'matches' => string '1' (length=1)
$query = "
SELECT t2.article_id, count(t2.keyword) AS matches
FROM article_tags t1
JOIN article_tags t2 ON (t1.keyword = t2.keyword AND t1.article_id != t2.article_id)
WHERE t1.article_id = ".$article_id."
GROUP BY t2.article_id
ORDER BY matches DESC
LIMIT 5";
if($query = $this->db->query($query)){
if($query->num_rows() > 0){
foreach($query->result_array() as $id => $article){
$articles[$id] = $this->fetch_article($article['article_id']);
}
} else {
$articles = array();
}
} else {
$articles = array();
}
return $articles;
}
发布于 2012-09-29 13:51:16
基本上你的想法是正确的-在article_tags表上建立一个自我连接。有一些你应该改进的地方:
tag_id而不是article_id,因为您希望按相关性对文章进行排序,并且匹配标签的计数指示tag_id而不是keyword上的relevance.!=。只需获取所有相关文章,并简单地删除最相关的文章,这应该是当前文章本身,出于性能原因,articles上的articles上进行简单的选择。所以答案可能是这样的:
SELECT
A2.article_id, count(A2.tag_id) AS matches
FROM
article_tags A1
JOIN
article_tags ON A1.tag_id=A2.tag_id
WHERE
A1.article_id = 1
GROUP BY
A2.article_id
ORDER BY
matches DESC
LIMIT 6 -- instead of 5, because the first result would be the current article你应该得到一个有6个ids的数组,只需删除第一个ids,然后执行SELECT操作(例如在python中):
article_ids = article_ids[1:]
articles = cursor.execute(
"SELECT * FROM articles WHERE article_id IN (%s)" % ",".join(article_ids)
)https://stackoverflow.com/questions/12650125
复制相似问题