0

以下查询(针对教育应用程序)计算用户在特定练习中的得分。它适用于四个表 - 用户、钻头、问题和答案。每个问题都属于一个演练,每个答案都属于一个问题和一个用户(一个答案对于一个用户和一个问题来说是唯一的)。问题是多项选择,如果 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
4

1 回答 1

0

下面试试。假设您使用 answer.created 列的“他们已经回答了至少一个问题”的情况。这个想法是为一个用户获取所有问题并计算 isCorrect、rawScore、score(if case) 任何您需要的数据并按 question.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;
于 2013-02-10T06:32:04.940 回答