所以我不能 100% 确定你的逻辑,至于你将如何处理有 3 个正确选择并且只选择了其中 2 个的情况,或者如果只有 2 个正确的选择并且总共选择了 3 个,是这样吗?使问题不正确?
这个逻辑你必须决定,但我认为你需要逐个问题地查看你的数据,即检查有多少正确选项,给出了多少正确选项,然后你可以整体分析数据,唯一应该改变的逻辑是上面描述的场景:
WITH Questions AS
( SELECT SQ.QuestionID,
CorrectChoices = COUNT(NULLIF(SC.IsCorrect, 0)),
ChoicesGiven = COUNT(SA.ChoiceID),
CorrectChoicesGiven = COUNT(CASE WHEN SA.ChoiceID IS NOT NULL AND SC.IsCorrect = 1 THEN 1 END)
FROM SurveyQuestions SQ
INNER JOIN SurveyChoices SC
ON SQ.QuestionId = SC.QuestionID
LEFT JOIN SurveyAnswers SA
ON SA.QuestionId = SC.QuestionID
AND SA.ChoiceID = SC.ChoiceID
AND SA.UserName = 'John.Doe'
WHERE SQ.SurveyID = 10
GROUP BY SQ.QuestionID
)
SELECT TotalQuestions = COUNT(*),
TotalCorrect = COUNT(CASE WHEN CorrectChoicesGiven = CorrectChoices THEN 1 END),
PercentCorrect = CAST(100.0 * COUNT(CASE WHEN ChoicesGiven = CorrectChoices THEN 1 END) / COUNT(*) AS DECIMAL(5, 2)),
TotalCorrect2 = SUM(CorrectChoicesGiven),
PercentCorrect = CAST(100.0 * SUM(CorrectChoicesGiven) / SUM(CorrectChoices) AS DECIMAL(5, 2))
FROM Questions;
更新了 SQL Fiddle 上的示例
编辑
根据您评论中的逻辑,对于多项选择中错过的每个正确答案,分数都会按比例减少,同样,对于给出的任何错误答案,规则如下(在所有示例中,数字均指多项选择题其中有 3 个可能的正确答案)
如果给出的正确答案的数量与正确答案的总数相匹配,并且没有选择错误答案,则得分为 100%
如果给出的正确答案的数量与正确答案的总数相匹配,但给出了额外的错误答案,则分数会因错误选项占正确选项总数的百分比而降低(例如,当只有 3 个正确选项时选择 4 个选项会降低分数1/3,得分为 66.66%)
如果给出的答案数量超过了正确答案的数量,并且没有找到所有正确答案(例如给出了 4 个答案,只有 2 个正确),这会将额外答案的分数降低 1,正确答案的分数会降低未命中,减少 2/3,因此得分为 33%
整个方法可以简化为以下等式(确保 0 是可能的最低答案);
(Correct answers given - Extra answers given) / Total Correct answers
这种方法的缺陷是,在一个有 3 个可能正确答案的问题中,如果用户给出了 3 个不正确的选项,他们可以得到一个正确的答案,但仍然得 0 分。另一种更简单的方法是用户获得分数作为他们给出的较大选择和正确答案的百分比,因此在前面的示例中,用户将获得 25%(4 个选择中的 1 个正确答案),如果他们只从 3 个答案中选择了 1 个答案,他们仍然会得到 33% 是正确的,因为他们选择的答案少于正确数量。我已将此方法作为 Score2 和 Percentage2 包含在以下查询中,因此您可以做出选择
WITH Questions AS
( SELECT SQ.QuestionID,
CorrectChoices = COUNT(NULLIF(SC.IsCorrect, 0)),
ChoicesGiven = COUNT(SA.ChoiceID),
CorrectChoicesGiven = COUNT(CASE WHEN SA.ChoiceID IS NOT NULL AND SC.IsCorrect = 1 THEN 1 END),
ExtraChoicesGiven = CASE WHEN COUNT(SA.ChoiceID) > COUNT(NULLIF(SC.IsCorrect, 0)) THEN COUNT(SA.ChoiceID) - COUNT(NULLIF(SC.IsCorrect, 0)) ELSE 0 END
FROM SurveyQuestions SQ
INNER JOIN SurveyChoices SC
ON SQ.QuestionId = SC.QuestionID
LEFT JOIN SurveyAnswers SA
ON SA.QuestionId = SC.QuestionID
AND SA.ChoiceID = SC.ChoiceID
AND SA.UserName = 'John.Doe'
WHERE SQ.SurveyID = 10
GROUP BY SQ.QuestionID
), QuestionScores AS
( SELECT QuestionID,
Score = CASE WHEN CorrectChoicesGiven - ExtraChoicesGiven < 0 THEN 0
ELSE CAST(CorrectChoicesGiven - ExtraChoicesGiven AS FLOAT) / CorrectChoices
END,
Score2 = ISNULL(CAST(CorrectChoicesGiven AS FLOAT) / NULLIF(CASE WHEN ChoicesGiven > CorrectChoices THEN ChoicesGiven ELSE CorrectChoices END, 0), 0)
FROM Questions
)
SELECT TotalQuestions = COUNT(*),
TotalCorrect = SUM(Score),
PercentCorrect = CAST(100.0 * SUM(Score) / COUNT(*) AS DECIMAL(5, 2)),
TotalCorrect2 = SUM(Score2),
PercentCorrect2 = CAST(100.0 * SUM(Score2) / COUNT(*) AS DECIMAL(5, 2))
FROM QuestionScores;
更新的 SQL Fiddle