-2

史蒂夫福特在下面帮助我完成了这个查询。(再次感谢史蒂夫)。

SELECT SUM(CASE WHEN SC.IsCorrect = 1 THEN 1 ELSE 0 END) AS TotalQuestions,
  COUNT(SA.AnswerID) AS TotalCorrect,
  CAST(COUNT(SA.AnswerID) AS Float) / 
  SUM(CASE WHEN SC.IsCorrect = 1 THEN 1 ELSE 0 END) * 100 As Percentage
  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 SC.IsCorrect = 1 
  AND SQ.SurveyID = 10

下面是他的小提琴演示。

http://sqlfiddle.com/#!3/4c642/1

该查询旨在以下列格式显示调查结果:

总问题:_ 完全正确:_ 正确百分比_

在大多数情况下,它都有效。

但是,它仍然不能正确处理复选框。

例如,SurveyQuestions 表中有一个名为 AnswerType 的字段名称。

值为M表示多项选择答案,例如用户可以选中一个或多个框的复选框。 S代表单选按钮选择等单一答案。在这里,用户只能选择一个答案。最后,T 代表自由文本,用户可以输入他们喜欢的任何值。

我们并不太关心 T answerType。

Steve 的代码正确计算 Checkboxes 的值。

还有另一个字段称为 IsCorrect。

任何正确的答案,无论是单选还是多选,都存储在 isCorrect 位数据类型中的值为 1。

如果答案不正确,则 isCorrect 的值为 0。

我在史蒂夫的查询中看到的唯一问题是,如果值为 isCorrect = 1,那么它将其本身视为一个问题。

因此,如果您检查例如 2 个复选框,并将它们作为正确答案进行检查,Steve 的代码会处理这两个单独的问题。

不管有多少框被选中作为正确答案,无论如何都将 M 的 answertType 视为一个问题?

感谢大家在这里提供的所有帮助。

4

2 回答 2

1

这是一个嵌套查询。最里面的查询是将问题与所有可能的答案连接起来,然后左连接到用户做出的实际选择。仅基于选择表的实际正确可能答案的计数,然后是从答案表中输入的实际正确答案。我得到了正确答案的计数和提供的实际答案的计数。这样,最终的“正确”答案是问题正确答案计数与用户正确答案计数相匹配的地方......并且用户提供的总答案是相同的。这将处理具有 2 个正确答案的问题实例和一个人选择 3 个选择,其中 2 个是正确的......所以 2 = 2 是可以的,但是当它与 3 个选择相比时会失败——用户 OVER PICKED。如果用户只选择一个选项并且那个选项是正确的,也可以处理......

分组是按问题进行的,所以那些单身的人只会有一个可能的正确答案计数 1 和 1 个可能的正确答案(或没有)。多个将被汇总,因此它也将是一个单一的条目问题。

然后,我将这些总计汇总为单行 FinalCorrectAnswers 和 TotalQuestions。

然后

SELECT
      FinalCorrectAnswers,
      TotalQuestions,
      ( FinalCorrectAnswers / ( 1.000 * TotalQuestions )) * 100.00 as Percentage
from
(
SELECT
      SUM( case when AnsByType.CorrectChoices = AnsByType.CorrectAnswers
                 AND AnsByType.CorrectChoices = AnsByType.TotalAnswersProvided
              then 1.000 else 0.000 end) as FinalCorrectAnswers,
      sum( 1 ) as TotalQuestions
   from
      ( SELECT 
              SQ.QuestionID,
              SUM( case when SCM.IsCorrect = 1 then 1 else 0 end ) as CorrectChoices,
              SUM( case when SCM.IsCorrect = 1 
                         AND NOT MAnswers.ChoiceID IS NULL
                      then 1 else 0 end ) as CorrectAnswers,
              COUNT( MAnswers.ChoiceID ) as TotalAnswersProvided
           from 
              SurveyQuestions SQ
                 Join SurveyChoices SCM
                    ON SQ.QuestionID = SCM.QuestionID
                    LEFT JOIN SurveyAnswers MAnswers
                       ON SCM.QuestionID = MAnswers.QuestionID
                       AND SCM.ChoiceID = MAnswers.ChoiceID
                       AND MAnswers.UserName = 'John.Doe'
           where
              SQ.SurveyID = 10
           group by
              SQ.QuestionID ) AnsByType  ) FinalSum

根据 SQLFiddle 的示例数据,我相信正确答案是 0%。如果您从答案中列出的同一样本集中运行此 sqlfiddle,则问题 8 有一个单选答案,但用户没有输入该值。问题 9 是一个多项选择答案,但该人只回答了一个正确答案。因此,由于两者都没有正确回答,因此答案是错误的,因此两个答案都不正确且百分比分数为零。

于 2013-08-06T16:16:33.213 回答
0

所以我不能 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

于 2013-08-06T15:21:17.453 回答