2

私は今日早く質問をしましたが、うまく機能する良い応答を受け取りました。回答が得られなかった質問の 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 つの回答が必要です。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そのセットに対して を適用し、ランク シーケンスと順序付けを確定します。

于 2012-04-17T13:34:22.853 に答える
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 に答える
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を簡単に選択できるようになります。

編集:私はあなたのグループを削除し、代わりに1行のPR回答が必要なように並べ替えました。

于 2012-04-17T13:05:40.540 に答える
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 に答える