我目前正在尝试检索最新帖子及其相关帖子(每个帖子的x号码)。我手头有以下查询:
SELECT id, title, content
(SELECT GROUP_CONCAT(title) FROM posts -- Select title of related posts
WHERE id <> p.id AND id IN (
SELECT p_id FROM tagsmap -- Select reletad post ids from tagsmap
WHERE t_id IN (
SELECT t_id FROM tagsmap -- Select the tags of the current post
WHERE p_id = p.id)
) ORDER BY id DESC LIMIT 0, 3) as related
FROM posts as p ORDER BY id DESC LIMIT 5
我的数据库结构很简单:一个帖子表。标签表。还有一个tagsmap表,我将帖子与标签相关联。
这个查询工作正常(虽然我不知道它的性能,因为表中没有很多行 - 也许解释可以帮助我,但现在情况并非如此)。
我真正需要的是检索相关帖子的ID及其标题。
所以我想做SELECT GROUP_CONCAT(title), GROUP_CONCAT(id)
,但我知道会导致错误。那么在这种情况下,检索id和标题的最佳方法是什么?我不想重写整个子查询只是检索id。应该有另一种方式。
修改
SELECT p1.id, p1.title, p1.content,
group_concat(DISTINCT p2.id) as 'P IDs',
group_concat(DISTINCT p2.title) as 'P titles'
FROM posts as p1
LEFT JOIN tagsmap as tm1 on tm1.p_id = p1.id
LEFT JOIN tagsmap as tm2 on tm2.t_id = tm1.t_id and tm1.p_id <> tm2.p_id
LEFT JOIN posts as p2 on p2.id = tm2.p_id
GROUP BY p1.id
ORDER BY p1.id desc limit 5;
最后这是我用过的查询。我删除了Where子句,因为它没有必要并使用LEFT JOIN
而不是JOIN
,否则会忽略没有标记的帖子。最后将DISTINCT
添加到group_concat中,因为它连接了重复的行(例如,如果帖子有多个带有相关帖子的常用标签,则会导致重复的连接)。
上面的查询完美无缺。谢谢大家。
答案 0 :(得分:2)
SELECT id, title, content
(SELECT GROUP_CONCAT(concat(cast(id as varchar(10)), ':', title)) FROM posts -- Select title of related posts
WHERE id <> p.id AND id IN (
SELECT p_id FROM tagsmap -- Select reletad post ids from tagsmap
WHERE t_id IN (
SELECT t_id FROM tagsmap -- Select the tags of the current post
WHERE post_id = p.id)
) ORDER BY id DESC LIMIT 0, 3) as related
FROM posts as p ORDER BY id DESC LIMIT 5
答案 1 :(得分:2)
好的 - 这会有效,并且它具有消除子查询的额外优势(当你获得大量记录时可能会减慢你的速度):
SELECT p1.id, p1.title, p1.content,
group_concat( p2.id) as 'P IDs',
group_concat( p2.title) as 'P titles'
FROM posts as p1
JOIN tagsmap as tm1 on tm1.p_id = p1.id
JOIN tagsmap as tm2 on tm2.t_id = tm1.t_id and tm1.p_id <> tm2.p_id
JOIN posts as p2 on p2.id = tm2.p_id
WHERE p2.id <> p1.id
GROUP BY p1.id
ORDER BY p1.id desc limit 5;
我们在这里做的是从帖子的第一个版本中选择你想要的内容,通过post.id将它们连接到tagsmap,按标签id自行连接到tagsmap以获取所有相关的标签,然后加入回另一个帖子(p2)以获取这些相关标签所指向的帖子。
使用GROUP BY丢弃所有加入的副本,你就在那里。