这是每个 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
针对该集合应用,然后最终确定排名顺序和排序。