我正在制作一个 QA 网站,与 SO 不同。我想列出我数据库中的所有问题,计算每个问题的投票数和答案数,然后找出特定用户是否已经为每个问题投票。在同一个查询中。
让我备份并提供一些背景信息。我有以下 SQL 表:
qa_questions => questionid title text
qa_votes => voteid questionid userid
qa_answers => answerid text questionid userid
第一个是问题表,其中包含数字 ID、标题和文本。用户可以为问题投票。只有赞成票。每个用户可以为他喜欢的多个问题投票,但每个问题只能投票一次。每当用户为一个问题投票时,都会在表格中添加一个条目votes
,记录 quesitonid 和 userid。answers 表存储每个答案的数字 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
好的,到目前为止一切顺利。现在我想把这两个表结合起来,所以我干脆对qid进行一个join:
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
嗯……呸。这行得通,但我不禁觉得它比它需要的要丑得多......有没有办法可以简化这个?