これは、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そのセットに対して を適用し、ランク シーケンスと順序付けを確定します。