所以我有一个试图抓住“相关帖子”的查询。
类别与帖子有一对多的关系。标签具有多对多关系。所以我的表看起来大致如下:
posts table:
id | category_id | ... | ...
tags table:
id | ... | ...
post_tag intermediate table:
id | post_id | tag_id | ... | ...
所以,如果我已经有一个Post行,那么抓住它的“相关”帖子。我的逻辑大致是我想只抓取属于同一类别的帖子,但是按照与原始帖子匹配的标签数量来订购这些帖子。因此,同一类别中与原始帖子具有完全相同标签的其他帖子应该是非常高的匹配,而仅匹配3/4标签的帖子将显示在结果中较低。
这是我到目前为止所做的:
SELECT *
FROM posts AS p
WHERE p.category_id=?
ORDER BY ( SELECT COUNT(id)
FROM post_tag AS i
WHERE i.tag_id IN( ? )
)
LIMIT 5
绑定: 初始帖子类别ID; 初始帖子标签ID;
显然,这不会通过子选择中的正确值实际排序结果。我无法想到如何加入这个以达到正确的结果。
提前致谢!
答案 0 :(得分:3)
试试这个,
SELECT posts.*
FROM posts,(SELECT p.id,
Count(pt.tag_id) AS count_tag
FROM posts AS p,
post_tag AS pt
WHERE p.category_id = '***'
AND pt.post_id = p.id
AND pt.tag_id IN(SELECT tag_id
FROM post_tag
WHERE post_tag.post_id = '***')
GROUP BY p.id
) temp
WHERE posts.id =temp.id ORDER BY temp.count_tag desc
您可以填写***
,因为您已有1个帖子行
答案 1 :(得分:3)
如果我正确地剔除了你的问题,这就是你要找的东西:
SELECT p.*,
Count(pt.tag_id) AS ord
FROM posts AS currentpost
JOIN posts AS p
ON p.category_id = currentpost.category_id
AND p.id != currentpost.id
JOIN post_tag AS pt
ON pt.post_id = p.id
AND pt.tag_id IN (SELECT tag_id
FROM post_tag
WHERE post_id = currentpost.id)
WHERE currentpost.id = ?
GROUP BY p.id
ORDER BY ord DESC
BINDINGS:Initial posts.id
;
并且您只需要在我的版本中指定当前帖子的ID,这样您就不必事先获取帖子标签并将其格式化为in子句
编辑: 这应该是一个更快的查询,通过避免双重加入帖子,如果你不喜欢用户变量只是替换所有currentpostid?和三重绑定post_id:
set @currentpostid = ?;
select p.*, count(pt.tag_id) as ord
from posts as p,
join post_tag as pt
on pt.post_id = p.id
and pt.tag_id in (select tag_id from post_tag where post_id = @currentpostid)
where p.category_id = (select category_id from posts where id=@currentpostid)
and p.id != @currentpostid
group by p.id
order by ord desc;