2016-11-13 10 views
0

正確なコメント数、投票数、アクティブユーザーの投票数を返すようにMySQLクエリを構成する際に問題があります。コメント数、投票数、アクティブユーザーが投票したかどうかを選択する方法

私のテーブルには、私のクエリは、この

SELECT 
    wall_posts.*, 
    COUNT(comments.wall_id) AS comment_count, 
    COALESCE(SUM(v1.vote), 0) AS vote_tally, 
    v2.vote 
FROM 
    wall_posts 
    LEFT JOIN comments ON wall_posts.id = comments.wall_id 
    LEFT JOIN votes v1 ON wall_posts.id = v1.wall_id 
    LEFT JOIN votes v2 ON wall_posts.id = v2.wall_id AND v2.username=:username 
WHERE 
    symbol =: symbol 
GROUP BY 
    wall_posts.id 
ORDER BY 
    date DESC 
LIMIT 15 
それは、常に特定のアクティブユーザーの投票のための正しい値を返すために働く

のように見えます

wall_posts (id, message, username, etc) 
comments (id, wall_id, username, text, etc) 
votes  (id, wall_id, vote (+1 or -1), username) 

ある(+1または-1)、または場合はnull投票しませんでした。項目にコメントがない場合、合計投票総額は正しいです。コメントがある場合、投票総額は常にコメント数と等しくなります。下位票がある場合はマイナス記号が付きますが、常にコメント数と同じです。

私はその明らかな方法アイブは私のテーブルを接続すると思いますが、その私にこれを説明することができます誰かにコメント数、1000000ポイントのコピーがなぜ私はちょうど把握カント:)

答えて

0

あなたが集計操作を実行する必要がありますサブクエリで今のところ、すべてのテーブルをまとめて(事前集計)一緒にJOINです。集約(およびGROUP BY)を削除すると、実際に何も意味しない大量のデータが表示されます。そして、あなたはそれがあなたの元の壁のデータと結合問い合わせることができ

CREATE VIEW walls_posts_stats AS 

SELECT 
    wall_posts.id, 
    COALESCE(comments_stats.comment_count, 0) AS comment_count, 
    COALESCE(votes_stats.vote_tally, 0) AS vote_tally 
FROM 

    wall_posts 

    LEFT OUTER JOIN 
    (
     SELECT 
      wall_id, 
      COUNT(*) AS comment_count 
     FROM 
      comments 
     GROUP BY 
      wall_id 
    ) AS comments_stats ON wall_posts.id = comments_stats.wall_id 

    LEFT OUTER JOIN 
    (
     SELECT 
      wall_id, 
      SUM(vote) AS vote_tally 
     FROM 
      votes 
     GROUP BY 
      wall_id 
    ) AS votes_stats ON wall_posts.id = votes_stats.wall_id 

代わりに、これを(私はVIEWを使用しています注意してください)してみてください

SELECT 
    wall_posts.*, -- note: avoid the use of * in production queries 
    stats.comment_count, 
    stats.vote_tally, 
    user_votes.vote 
FROM 
    wall_posts 
    INNER JOIN walls_posts_stats AS stats ON wall_posts.id = stats.id 
    LEFT OUTER JOIN 
    (
     SELECT 
      wall_id, 
      vote 
     FROM 
      votes 
     WHERE 
      username = :username 
    ) AS user_votes ON wall_posts.id = user_votes.wall_id 
ORDER BY 
    date DESC 
LIMIT 15 

仮にあなたにそれを組み合わせることができ単一の大きなクエリ(基本的には、VIEW本体をコピーしてINNER JOIN walls_posts_stats節に貼り付けます)が、保守性の問題が導入されると思います。

MySQLはビューをサポートしていますが、パラメータ化ビュー(構成可能なテーブル値関数とも呼ばれ、ストアドプロシージャは構成可能ではありません)をサポートしていないため、user_votesサブクエリはwalls_posts_statsビューに含まれていません。

+0

こんにちは、返信いただきありがとうございます。その外観は私が心に留めていたものより少し複雑です! (主に、iveが意見を聞いたことがないので、今私はそれらを読み上げるでしょう。一つの質問でそれを行うことは不可能であると思いますか、意見がなくても、それを集計することは不可能ですこれを一つの声明で – Gravychain

関連する問題