2012-04-05 11 views
2

私は2つのテーブル、ブログ、投稿を持ち、それらの間には期待される関係があります。投稿は公開されるか、下書きされます。私は、公開された投稿と草稿投稿の数を含むすべてのブログを選択したいと思います。どうしたらいいですか?さまざまな結合からのカウントをSQLの同じテーブルに取得する方法は?

私はこのクエリを試してみました:

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 

が、私はpublished_post_countとdraft_post_countの両方に同じ番号で終わるとの両方のために間違っています。

は、その後、私は絶望的となったトライ:

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 

が、両方のケースで私は、同じ間違った結果が得られました。

これを行うには適切な方法はありますか?

ありがとうございました。

答えて

4

COUNTに興味があり、テーブルをJOINにすることもできます。そのため、publishedであり、1つ以上がdraftである1つ以上のpostがなければなりません。だから、多分これはあなたを助ける:

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 
+0

これは機能します。しかし、これは多くのクエリを実行するのと同じではありませんか? (N + 1) – Pablo

+0

いいえ。外部クエリに依存するサブクエリです。 COUNT(*)を実行してもそれほど効果的ではありません。 – Arion

+0

答えがうまくいけば、答えを受け入れることを検討するかもしれません。 – Arion

1

試してみてください。

GROUP BY blogs.id,published_posts.[theKeyOfThisTable],draft_posts.[theKeyOfThisTable] 

あなたはあなたが異なる状態を数えるかもしれない句

1

「でグループ」あなたの「選択」の列が含まれている必要がありますようブログに参加する:

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 
+0

大きなテーブルでは、相関サブクエリアプローチよりもはるかに高速であることが期待されますが、両方を確認する価値があります。私はCASE述語に "else 0"節がないことに驚きましたが、クイックテストではそれがなくてもうまく動作することが示唆されています。 – kgrittn

関連する問題