Reputation: 10611
I'm making a very simple forum with one table called forum_posts. I store both the replies and the posts in that same table because I've found that works pretty well for comments system I made before.
If the post is a reply, it has a reply_id that is the post_id of the post it is replying to. If it is a 'root post' so to speak, it has a 0 for the reply_id.
I already have the number of views. But I'd like to get the number of replies for each record in the results.
How would I do that?
SELECT a.account_id, a.store_name, p.post_id, p.post_title, p.post_text, p.views, p.creation_timestamp, p.update_timestamp
FROM forum_posts AS p
INNER JOIN accounts AS a
ON p.account_id = a.account_id
WHERE p.reply_id > 0
As you can probably guess, I'm making the forum listings where people choose a forum post to go and view.
Upvotes: 0
Views: 127
Reputation: 798
SELECT account_id, store_name, post_id, post_title, post_text, views, creation_timestamp, update_timestamp, IF(reply_id IS NOT NULL, replies, 0)
FROM (
SELECT a.account_id, a.store_name, p.post_id, p.post_title, p.post_text, p.views, p.creation_timestamp, p.update_timestamp, r.reply_id, COUNT(*) as replies
FROM forum_posts AS p
INNER JOIN accounts AS a
ON p.account_id = a.account_id
LEFT JOIN forum_posts AS r
ON p.post_id = r.reply_id
WHERE p.reply_id = 0
GROUP BY p.post_id
) AS sq
It also seems that you need p.reply_id = 0
if you want to show only "root" posts (forum threads) rather than replies.
Outer query makes sure that the posts with no replies (which are still returned in the inner query) are printed with the number of replies 0 rather than 1 (which would be incorrect obviously).
Upvotes: 1
Reputation: 1769
You will need to join posts against itself and count it to get the number of replies. This isn't particularly efficient over millions of forum posts - most forums denormalize this and maintain a post count attribute separately.
However, in keeping with what you have, something like (untested)...
SELECT a.account_id, a.store_name, cp.* FROM
(
SELECT p.post_id, p.post_title, p.post_text, p.views, p.creation_timestamp,
p.update_timestamp, p.account_id, (COUNT(*) - 1) as replies
FROM forum_posts AS p
LEFT JOIN forum_posts AS p1 ON p1.reply_id > 0 AND p1.reply_id = p.post_id
GROUP BY p.post_id
)
AS cp
INNER JOIN accounts AS a ON cp.account_id = a.account_id
WHERE cp.replies > 0
The end WHERE
is optional. I just copied it from your first query. It's also worth noting that this is MySQL specific as it uses the GROUP BY
without a full list of non-aggregated columns (but you tagged your question as MySQL so no problem).
Upvotes: 1