我需要做的很简单......但凌晨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
我该如何解决这个问题?
答案 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))