4

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

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

唯一的问题是,当我加入帖子表时,它会加入表中的第一个记录,而不是最后一个记录,这表示该论坛中的最后一个帖子。

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

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

我怎样才能解决这个问题?

4

1 回答 1

5

您遇到的问题是经典的Ambiguous 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))
于 2009-05-19T06:27:37.483 回答