如何扩展SQL计算查询以为多个父行提供结果

时间:2013-02-10 04:27:58

标签: mysql sql

以下查询(针对教育应用)计算特定练习中的用户分数。它适用于四个表 - 用户,钻取,问题和答案。每个问题都属于一个练习,每个答案都属于一个问题和一个用户(答案对于用户和问题是唯一的)。如果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

1 个答案:

答案 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;