What I need done is simple… but its 3am and Im probably overlooking the obvious.
Im coding a simple forum. One table stores the forum titles, descriptions, etc, while the other stores the posts. In the forum listing, that shows the list of all forums, I want to grab the latest post in each forum, and display the post subject, poster and post ID, and date. Simple.
The only problem is, when I join to the posts table, it joins to the first record in the table, not the last, which would denote the last post in that forum.
Here is the simplified query that gets a list of forums + data for the “latest” post (which now functions as “first post”).
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
How can I fix this?
The problem you’re hitting is the classic Ambiguous GROUP BY issue. This is particular to MySQL, because other RDBMS (and standard SQL) won’t allow your query at all. Your query fails the Single-Value Rule, because you haven’t listed all non-aggregated columns in the
GROUP BY.Here’s a solution demonstrating my favorite way of getting greatest row per group:
If
p2.post_id IS NULL, that means no post is found inp2which is greater than the post found inp1.Ergo,
p1is the latest post (assumingpost_idis auto-incrementing).Re comment:
No problem. Just use a column that is guaranteed to distinguish an earlier post from a later post. You mention
post_date. In the case of ties, you’ll have to break ties with another column (or columns) that will be sure to be in chronological order.