Kazuo
Kazuo

Reputation: 397

Getting mutliple threads and their latest post from a database using one query

I want to code a forum with subforums and need to create an overview of a subforum displaying the latest post of a thread in a html-table.

I have two mysql tables:

forum_threads:

id int(10)
forumid int(10)
title varchar(80)
accesslevel int(2)
locked enum('yes', 'no')

forum_post:

id int(10)
threadid int(10)
userid int(10)
posted datetime
edited datetime
message text

My query looks like that:

SELECT * FROM `forum_threads` LEFT JOIN `forum_post`
ON (forum_post.threadid = forum_threads.id)
WHERE forumid='$secfid'
AND accesslevel<='$secuserlevel'
ORDER BY forum_post.posted DESC
LIMIT $qStart,$ppp

Where $secfid is the id of the subforum.

My problem ist that the result set contains all posts and because of that, each thread is contained as many times as its number of posts. Each thread should only be there once and only with the latest post in it's result row.

I could solve it with an additional subquery but I wanted to ask if there is a better way to do it.

I also found something like this on stackoverflow:

SELECT * FROM `forum_post` fp
JOIN `forum_threads` ft
ON (fp.threadid = ft.id) WHERE forumid=1
AND accesslevel<='100'
AND NOT EXISTS (
    SELECT * FROM forum_post fp2
    JOIN forum_threads ft2
    ON fp2.threadid = ft2.id
    WHERE ft.forumid = ft2.forumid
    AND fp.posted < fp2.posted
) LIMIT 0,20

This returns all the desired information but only from the thread with the latest post.

Upvotes: 0

Views: 433

Answers (1)

Pat
Pat

Reputation: 25675

I would do it by joining on a subselect that retrieved the latest post from each thread.

The subselect will give you back the latest posted date in each thread. This can then be used to get thread and post data:

SELECT
    thread.title,
    post.text
FROM
    forum_thread thread

-- Get latest post from each thread 
JOIN (
    SELECT      
        MAX(post.posted) as posted,
        post.threadid
    FROM
        forum_post post

    JOIN 
        forum_thread thread
    ON 
        post.threadid = thread.id

    -- Limit the forum and security levels  
    WHERE
        thread.forumid = '$secfid'
        AND thread.accesslevel <= '$secuserlevel'       
    GROUP BY
        post.threadid

) latest_post
ON 
    thread.id = latest_post.threadid

-- Get post data for the latest post
JOIN
    forum_post post
ON
    latest_post.threadid = post.threadid
    AND latest_post.posted = post.posted

LIMIT
    $qStart, $ppp;

Upvotes: 1

Related Questions