我如何加入表中的最新记录?

时间:2009-05-19 06:13:48

标签: php mysql greatest-n-per-group

我需要做的很简单......但凌晨3点和我可能会忽略显而易见的事情。

我正在编写一个简单的论坛。一个表存储论坛标题,描述等,而另一个表存储帖子。在论坛列表中,显示所有论坛的列表,我想在每个论坛中获取最新帖子,并显示帖子主题,海报和帖子ID以及日期。简单。

唯一的问题是,当我加入posts表时,它会加入表中的第一条记录,而不是最后一条记录,这将表示该论坛中的最后一篇文章。

这是一个简化的查询,它获取“最新”帖子的论坛+数据列表(现在作为“第一篇帖子”)。

SELECT forum_title, forum_id, post_subject, post_user, post_id, post_date FROM board_forums 
     LEFT JOIN board_posts 
     ON (forum_id = post_parentforum AND post_parentpost = 0) 
WHERE forum_status = 1
GROUP BY forum_id
ORDER BY forum_position

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:5)

您遇到的问题是经典的不明确的GROUP BY 问题。这是MySQL特有的,因为其他RDBMS(和标准SQL)根本不允许您的查询。您的查询未通过单值规则,因为您尚未列出GROUP BY中的所有非汇总列。

这是一个解决方案,展示了我最喜欢的每组获得最大排的方式:

SELECT f.forum_title, f.forum_id, p1.post_subject, p1.post_user, 
  p1.post_id, p1.post_date 
FROM board_forums f
LEFT JOIN board_posts p1
  ON (f.forum_id = p1.post_parentforum AND p1.post_parentpost = 0)
LEFT JOIN board_posts p2
  ON (f.forum_id = p2.post_parentforum AND p2.post_parentpost = 0 
      AND p1.post_id < p2.post_id)
WHERE p2.post_id IS NULL AND f.forum_status = 1
ORDER BY f.forum_position;

如果p2.post_id IS NULL,则表示p2中没有找到比p1中找到的帖子更大的帖子。

Ergo,p1是最新帖子(假设post_id是自动递增的)。


评论:

  

这个问题很轻微。具有最高ID的post_id不一定是最新的帖子。

没问题。只需使用保证将早期帖子与后期帖子区分开的列。你提到post_date。在关系的情况下,你将不得不打破与其他列(或列)的联系,这将确保按时间顺序排列。

LEFT JOIN board_posts p2
  ON (f.forum_id = p2.post_parentforum AND p2.post_parentpost = 0 
    AND (p1.post_date < p2.post_date 
      OR p1.post_date = p2.post_date AND p1.post_millisecond < p2.post_millisecond))