Reputation:
I have been working on a blog system recently, and I ran into an issue. I have two tables, one for blog posts, and another for comments on those posts. This is the query that I am currently using for retrieving of all post information and also the number of comments:
SELECT bp.*, COUNT(bpc.id) AS post_comments
FROM blog_posts AS bp
LEFT JOIN blog_post_comments AS bpc ON bpc.post_id = bp.id
LIMIT 0, 10
Now, as I stated in the title, this only returns me data about one post, although it should return 10 posts. Why is this so?
Thanks!
Upvotes: 1
Views: 1397
Reputation: 270607
You are missing the GROUP BY
clause, and since MySQL is lenient about aggregate functions and columns in the SELECT
not appearing in the group by, it collapses down to one row showing the total count, but mixed column values from other columns.
SELECT bp.*, COUNT(bpc.id) AS post_comments
FROM blog_posts AS bp
LEFT JOIN blog_post_comments AS bpc ON bpc.post_id = bp.id
GROUP BY bp.id
LIMIT 0, 10
The more portable way to do this for RDBMS other than MySQL would be to join against a subquery that returns only the post_id
and the number of posts per id, allowing the rest of the columns from blog_posts
to be selected without appearing in the GROUP BY
.
SELECT
bp.*,
bcount.counts
FROM
blog_posts AS bp
LEFT JOIN (
SELECT post_id, COUNT(*) AS counts
FROM blog_post_comments
GROUP BY post_id
) bcounts ON bp.id = bcounts.post_id
Upvotes: 4
Reputation: 2549
Since you use COUNT, it will consider all posts as the same. Try this to see if it works:
SELECT bp.*, COUNT(bpc.id) AS post_comments
FROM blog_posts AS bp
LEFT JOIN blog_post_comments AS bpc ON bpc.post_id = bp.id
GROUP BY bp.id
LIMIT 0, 10
I'm not sure if that's the problem. Just guessing. :)
Upvotes: 2
Reputation: 11080
You get one record because COUNT() is an aggregate function. You should add a GROUP BY clause and COUNT() will work as you wanted.
Upvotes: 1