以下查询(针对教育应用)计算特定练习中的用户分数。它适用于四个表 - 用户,钻取,问题和答案。每个问题都属于一个练习,每个答案都属于一个问题和一个用户(答案对于用户和问题是唯一的)。如果answer.selectedChoice = 1,则问题是多项选择且答案是正确的。用户的演练分数基于该演习的最近五个答案,并且分配给正确答案的权重将根据答案的速度进行缩放。
我正在试图弄清楚如何扩展此查询,以便不是仅获取特定练习的用户分数,而是可以获得每个练习的用户分数,并且他们至少回答了一个问题。我一直在调查将其重写为相关子查询,但到目前为止,我的努力已经缩短了。任何帮助将不胜感激。
SELECT data.*,
SUM(data.isCorrect * (IF(rawScore < 0, 0, IF(rawScore > 1, 1, rawScore)))) / 5 AS score
FROM
(SELECT
answer.id,
IF(answer.selectedChoice = 1, 1, 0) AS isCorrect,
(1 - (answer.timeElapsed - question.baseTime) / (4 * question.baseTime)) as rawScore
FROM
answer,
question
WHERE
answer.questionID = question.id AND
question.drillID = :drillID AND
answer.userID = :userID
ORDER BY
answer.created DESC
LIMIT
5) as data
答案 0 :(得分:0)
请尝试以下操作。假设“他们已经回答了至少一个问题”的条件,你正在使用answer.created专栏。 这个想法是为一个用户获取所有问题并计算isCorrect,rawScore,得分(如果是大小写)您需要的任何数据并按问题分组.drillID,answer.userID(每次演习的用户得分),然后使用HAVING子句只得到回答至少一个问题的用户(他们至少回答了一个问题)。
下面的查询可能会得到错误的结果 - 请发布表结构和示例数据,我可以为您创建一个演示。
SELECT
answer.id,
IF(answer.selectedChoice = 1, 1, 0) AS isCorrect,
(1 - (answer.timeElapsed - question.baseTime) / (4 * question.baseTime)) as rawScore
-- SUM(data.isCorrect * (IF(rawScore < 0, 0, IF(rawScore > 1, 1, rawScore)))) / 5 AS score
-- SUM(IF(answer.selectedChoice = 1, 1, 0) * (IF(1 - (answer.timeElapsed - question.baseTime) / (4 * question.baseTime)) < 0, 0, IF((1 - (answer.timeElapsed - question.baseTime) / (4 * question.baseTime)) > 1, 1, (1 - (answer.timeElapsed - question.baseTime) / (4 * question.baseTime)))))) / 5 AS score
FROM answer a
INNER JOIN question q ON answer.questionID = question.id
GROUP BY
question.drillID, answer.userID
WHERE
answer.userID = :userID
HAVING
COUNT(answer.created) >= 1;