SOとは異なり、QAサイトを作成しています。データベースにあるすべての質問を一覧表示し、各質問の投票数と回答数をカウントして、特定のユーザーが各質問にすでに投票しているかどうかを確認したいと思います。同じクエリで。
バックアップして、少しコンテキストを説明しましょう。私は次のSQLテーブルを持っています:
qa_questions => questionid title text
qa_votes => voteid questionid userid
qa_answers => answerid text questionid userid
1つ目は質問の表で、数値ID、タイトル、およびテキストが含まれています。ユーザーは質問に投票できます。賛成票のみがあります。各ユーザーは、好きなだけ質問に投票できますが、質問ごとに1回だけ投票できます。ユーザーが質問に投票するたびに、エントリがvotes
テーブルに追加され、quesitonidとuseridが記録されます。回答テーブルには、各回答の数値IDとテキストが格納され、回答されている質問と回答を送信したユーザーも参照されます。
すべての質問のリストを取得し、各質問の投票数を数え、特定のユーザー(ユーザー#1など)が質問に投票したかどうかを示すには、次のようにします。
SELECT qa_questions.questionid AS qid, title, text, COUNT( voteid ) AS num_votes,
MAX(CASE WHEN qa_votes.userid=1 THEN 1 ELSE 0 END ) AS voted_for
FROM qa_questions
LEFT JOIN qa_votes ON qa_questions.questionid = qa_votes.questionid
GROUP BY qa_questions.questionid
これは機能します。これが返すものの例:
qid title text num_votes voted_for
1 What is 2 + 2? I want to know the answer to this math question! 2 1
(voted_for
列の1はTRUE
を表し、現在のユーザーがこの質問に投票したことを示します)。
これを行うことで、各質問の回答数を確認することもできます。
SELECT qa_questions.questionid AS qid, COUNT( answerid ) AS num_answers
FROM qa_questions
LEFT JOIN qa_answers ON qa_questions.questionid = qa_answers.questionid
GROUP BY qa_questions.questionid
これは次を返します:
qid num_answers
1 1
2 2
3 0
4 3
さて、これまでのところとても良いです。ここで、これら2つのテーブルを結合したいので、qidで結合するだけです。
SELECT t1.qid, title, TEXT, num_votes, voted_for, num_answers
FROM (
SELECT qa_questions.questionid AS qid, title, text, COUNT( voteid ) AS num_votes,
MAX(CASE WHEN qa_votes.userid=1 THEN 1 ELSE 0 END) AS voted_for
FROM qa_questions
LEFT JOIN qa_votes ON qa_questions.questionid = qa_votes.questionid
GROUP BY qa_questions.questionid
) AS t1
JOIN (
SELECT qa_questions.questionid AS qid, COUNT( answerid ) AS num_answers
FROM qa_questions
LEFT JOIN qa_answers ON qa_questions.questionid = qa_answers.questionid
GROUP BY qa_questions.questionid
) AS t2
ON t1.qid = t2.qid
うーん....うん。これは機能しますが、必要以上に醜いと感じずにはいられません...これを単純化する方法はありますか?