1

我目前正在尝试检索最新帖子及其相关帖子(每个帖子的 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

我的数据库结构很简单:一个帖子表。一个标签表。还有一个标签映射表,我将帖子与标签相关联。

这个查询工作正常(虽然我不知道它的性能,因为我的表中没有很多行——也许解释可以帮助我,但现在情况并非如此)。

我真正需要的是检索相关帖子的 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 因为它正在连接重复的行(例如,如果一个帖子有多个带有相关帖子的公共标签,则会导致重复的连接)。

上面的查询完美运行。谢谢大家。

4

2 回答 2

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
于 2013-03-22T21:08:58.550 回答
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 丢弃所有加入的重复,你就在那里。

于 2013-03-22T21:31:28.180 回答