Reputation: 287390
I have two tables, blogs and posts, with the expected relationship between them. Posts can be published or draft. I want to select all blogs with the counts of published and draft posts. How can I do it?
I tried this query:
SELECT blogs.*,
COUNT(published_posts.*) AS published_post_count,
COUNT(draft_posts.*) AS draft_post_count
FROM blogs
JOIN posts AS published_posts ON published_posts.blog_id=blogs.id AND
published_posts.state = "published"
JOIN posts AS draft_posts ON draft_posts.blog_id=blogs.id AND
draft_posts.state = "draft"
GROUP BY blogs.id
but I end up with the same number for both published_post_count and draft_post_count and being wrong for both.
Then I got desperate and trie:
SELECT blogs.*,
COUNT(published_posts.*) AS published_post_count,
COUNT(draft_posts.*) AS draft_post_count
FROM blogs
JOIN (SELECT * FROM posts WHERE posts.state="published") AS published_posts
ON published_posts.blog_id=blogs.id
JOIN (SELECT * FROM posts WHERE posts.state="draft") AS draft_posts
ON draft_posts.blog_id=blogs.id
GROUP BY blogs.id
but in both cases I had the same wrong results.
What's the proper way to do this?
Thanks.
Upvotes: 2
Views: 2097
Reputation: 19346
You might count different states and join back to blogs:
SELECT blogs.*, p.published_post_count, p.draft_post_count
FROM blogs
JOIN
(
SELECT posts.blog_id,
SUM(case when posts.state = 'published' then 1 end)
AS published_post_count,
SUM(case when posts.state = 'draft' then 1 end)
AS draft_post_count
FROM posts
GROUP BY blog_id
) p
ON p.blog_id=blogs.id
Upvotes: 2
Reputation: 832
Try :
GROUP BY blogs.id,published_posts.[theKeyOfThisTable],draft_posts.[theKeyOfThisTable]
as you should contain the columns of the "select" at your "group by" clause
Upvotes: 1
Reputation: 31239
If you are just interested in the COUNT
and you are also JOIN
ing the tables. So there has to be one or more post
that has been published
and one or more that is draft
. So maybe this will help you:
SELECT blogs.*,
(
SELECT COUNT(*)
FROM posts
WHERE posts.blog_id=blogs.id
AND posts.state = "published"
) AS published_post_count,
(
SELECT COUNT(*)
FROM posts
WHERE posts.blog_id=blogs.id
AND posts.state = "draft"
) AS draft_post_count,
FROM blogs
Upvotes: 4