これは、Y 例あたりの TOP X レコードの別の例です。すべての質問に対して、4 つの回答が必要です。LIMIT は実際には 2 回必要です...最初に適格な質問を制限し、質問の結果セットごとに常に「正しい」回答が含まれることを保証する回答の別の「ランキング」を行います。
したがって、私のアプローチは、最初に質問に対してランダムを適用してサブセットの結果を取得し、それを回答に結合して X を Y ごとに制限することです。その後、すべてをまとめることができます。ここで重要なことは、内部クエリを質問 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
てください。:=
最初に投稿したとき、「:」を 1 つ残していたため、誤ったエラーが発生する可能性がありました。また、「a.correct = 1」を使用して内部の「Order by」を修飾しました (エイリアス参照はありません)。最後に、外側の WHERE 句を の< 5
代わりにjust に変更しました<= 4
。私はこれらの最大の Y ごとの X のグループ化を数多く行ってきましたが、それらが機能することを知っていますが、確かに単純なものが欠けているだけです。
また、最初の値が 10 進数になるようにランダムを調整しましIF()
た。それ以外の場合、すべてのランダムは 1 (整数) に設定され、分数にはなりません。最初の位置ですべての正解を取得するために事前に並べ替えられ、SQLVars
そのセットに対して を適用し、ランク シーケンスと順序付けを確定します。