2

我今天早些时候问了一个问题,并收到了很好的回复。这个问题的第二部分从未得到回应,所以我再试一次。

SELECT q.id,q.question,a.question_id,a.answer, a.correct
FROM (SELECT * FROM questions q WHERE q.subject_id = 18
      ORDER BY RAND() LIMIT 5) q
JOIN answers a on q.id = a.question_id GROUP BY q.id, a.id

以上很好,并返回 5 个随机问题以及相应的答案。问题是每个问题有 9 个答案,其中 1 个是正确的(正确 = 1),其他是错误的(正确 = 0)。我不想要所有答案,而是想要正确的一个和 3 个其他随机答案。

我已经玩了几个小时了,却一无所获。

任何帮助,将不胜感激。

谢谢

史蒂夫

PS:也许最好通过php处理它,但我又不确定。对此的任何想法也会有所帮助。

4

4 回答 4

2

这是每个 Y 示例中 TOP X 记录的另一个示例。对于每个问题,您都需要 4 个答案。实际上需要两次限制...首先限制合格的问题,然后再对答案进行“排名”,以保证每个问题结果集中始终包含“正确”答案。

所以我的方法是首先对问题应用随机数,将其作为子集结果,然后将其加入答案并限制每个 Y 的 X。然后,我们可以把它全部包起来。这里的关键是内部查询必须按问题 ID 排序......并且“正确”答案的限定词始终位于第一位,但之后的任何内容都是随机的,总共包含 4 条记录。

然后,最终查询应用 WHERE 子句仅包括排名序列 <= 4 的位置(可能包含 1 个问题的所有 9 个答案,但随后应用最终的“ORDER BY”子句将问题保持在一起,但随机化答案,因此“正确”不再总是返回第一个位置。您可以删除这个外部“ORDER BY”子句用于测试目的,只是为了确认功能,然后再将其添加回来。

select
      FinalQA.*
   from
      ( select 
              QWithAllAnswers.*,
              @RankSeq := if( @LastQuestion = QWithAllAnswers.id, @RankSeq +1, 1 ) ARankSeq,
              @LastQuestion := QWithAllAnswers.id as ignoreIt
           from
              ( SELECT 
                      q.id,
                      q.question,
                      q.RandQuestionResult,
                      a.question_id,
                      a.answer, 
                      a.correct
                   FROM 
                      ( SELECT q.ID,
                               q.Question,
                               q.question_ID,
                               RAND() as RandQuestionResult
                           FROM 
                               questions q 
                           WHERE 
                               q.subject_id = 18 
                           ORDER BY RAND() 
                           LIMIT 5) JustQ
                      JOIN answers a 
                         on q.id = a.question_id
                   ORDER BY
                      JustQ.RandQuestionResult,
                      if( a.correct = 1,0.000000, RAND() 
              ) QWithAllAnswers,

              ( select @RankSeq := 0, @LastQuestion := 0 ) SQLVars

      ) FinalQA

   where
      FinalQA.ARankSeq < 5
   order by
      FinalQA.RandQuestionResult,
      rand()

几个小的变化......确保每个作业SQLVars都有:=。当我最初发布时,我留下了一个“:”,这可能会引发错误的错误。我还使用“a.correct = 1”(没有别名引用)限定了内部“排序依据”。最后,将外部 WHERE 子句更改为 just< 5而不是<= 4. 我已经完成了许多这些最棒的 X per Y 分组,并且知道它们有效,只是缺少一些简单的东西,我敢肯定。

此外,将IF()随机数调整为将第一个值设为小数,否则所有随机数都设置为 1(整数)并且从不分数...此外,对于应用 ORDERING 时可能出现的问题,我已经预先查询了所有 Q 和预先排序以在第一个位置获得所有正确答案,然后SQLVars针对该集合应用,然后最终确定排名顺序和排序。

于 2012-04-17T13:34:22.853 回答
1

试试这个:

SELECT q.id,q.question,a.question_id,a.answer, a.correct
FROM (SELECT * FROM questions q WHERE q.subject_id = 18
      ORDER BY RAND() LIMIT 5) q
JOIN answers a on q.id = a.question_id
ORDER BY q.id, a.correct, RAND()

这应该首先让你得到正确的答案,然后是随机顺序的错误答案。这应该使您可以轻松地在 php 代码中选择 1 + 3。

编辑:我删除了您的组,并将其按顺序排列,因为您想要一行公关答案。

于 2012-04-17T13:05:40.540 回答
1

为什么不使用 UNION 来获得好的答案和随机的错误答案?

SELECT q.id,q.question,a.question_id,a.answer, a.correct
FROM (SELECT * FROM questions q WHERE q.subject_id = 18
      ORDER BY RAND() LIMIT 5) q
  JOIN answers a on q.id = a.question_id 
WHERE a.correct = 0
GROUP BY q.id, a.id

UNION

SELECT q.id,q.question,a.question_id,a.answer, a.correct
FROM question q
  JOIN answers a on q.id = a.question_id 
WHERE q.subject_id = 18 
  AND a.correct = 1
于 2012-04-17T13:24:17.573 回答
0

您可以尝试使用子查询,例如:

(伪代码)

Select a.*, q.*
from questions q join answers a on q.id=a.question_id
where q.id in ( SELECT id FROM questions q1 WHERE q1.subject_id = 18 ORDER BY RAND() LIMIT 5 )
and a.id in ( SELECT id FROM answers a1 WHERE a1.question_id = q.id ORDER BY a1.correct desc, RAND() LIMIT 4)

(结束伪代码)

阅读所有答案并在代码中选择随机答案可能会更有效(不过,它们可以按correct降序排列,这样你就知道,第一个是正确的)。

于 2012-04-17T13:03:13.443 回答