2012-04-17 13 views
2

今日私は質問をして、うまく対応してくれました。私はもう一度やり直しているので、決して応答を得なかった質問の第二の部分がありました。mysql complex sql

上記は適切であり、対応する回答とともに5つのランダムな質問が返されます。問題は各質問に9つの回答があり、そのうちの1つは正しい(正しい= 1)、他は偽(正しい= 0)です。私はすべての答えを望むのではなく、正しいものと3つの他のランダムなものを望んでいます。

私はこれを何時間もプレイしており、どこにもいません。

ご協力いただければ幸いです。

おかげ

スティーブ

PS:たぶんそれは、PHPを経由してそれを処理する方が良いでしょうが、再び、私はよく分かりません。それについての考えも参考になります。

+0

私はあなたの他の質問をしようとしましたが、実際の解決策を得ることはできませんでした。他の人が参考にしたいと思うように、私が得た限りです:http://www.sqlfiddle.com/#!2/34906/34。なんらかの理由で、 'answers'の内部クエリの' ORDER BY RAND() 'が機能しません。 – mellamokb

+1

あなたはPHPでうまくいくでしょう。 MySQLには、Oracle/SQL Server/PostgreSQLで使用できる言語構造がありません。 – gbn

+0

@gbn:特に質問ごとに最大9個の回答しかないので、私は同意します。すべての答えをPHPに取り込み、そこでランダム化を行うのと同じくらい簡単になります。 – mellamokb

答えて

2

これは、例ごとのTOP Xレコードの別の例です。すべての質問に対して、あなたは4つの回答が必要です。 LIMITは実際には2回必要です...最初に適格な質問を制限し、「正しい」答えが常に質問結果セットに含まれることを保証する回答の別の「順位付け」を行います。

私のアプローチは、まずサブセットの結果としてそれを得るために質問に対してランダムを適用し、それを答えに結合し、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で確認してください割り当てのそれぞれについて:=を持っています。私が最初に投稿したとき、私は虚偽の誤りを投げかけたかもしれない1つの「:」を残しました。また、 "a.correct = 1"(エイリアス参照を持たない)を使用して内部の "Order By"を修飾しました。最後に、外側のWHERE句を<= 4の代わりに< 5に変更しました。私はこれらの最大のYグループごとにたくさんのことをして、彼らが働いていることを知っています。

また、IF()ランダムを最初の小数点以下の値に調整します。そうでない場合、すべての乱数は1(整数)に設定され、決して小数点以下になりません... ORDERINGが適用されるときの問題については、 - すべての質問と最初の位置にすべての正解を得るためにあらかじめソートされたAを質問した後、そのセットに対してSQLVarsを適用し、ランク順序と順序を確定します。

+0

私はあなたの提案を試み、次のエラーが発生しました...#1064 - SQL構文にエラーがあります。 'QWithAllAnswers QWithAllswers.ARankSeq <= 4 order by Q'(27行目) – SteveF

+0

@ user1292262の近くで使用する正しい構文については、ご使用のMySQLサーバーのバージョンに対応するマニュアルを参照してください。修正された回答とSQLの調整のコメントを参照してください。 – DRapp

+0

いくつかのタイプミスを修正し、ここであなたのソリューションを構築しました:http://www.sqlfiddle.com/#!2/34906/52。私は、あなたがモデル化した例を知っています。私は同じものを考えました。しかし、OPにコメントして投稿した自分の解決策と全く同じ問題を抱えているように見えます。奇妙な理由で回答をランダム化するのではなく、各質問から最初の4つの回答を取得するだけです。とても奇妙です。たぶんsqlfiddle.comやMySQLのバージョンだけで問題になるのでしょうか?私はMySQLインスタンスを自分でテストすることはできません。 – mellamokb

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降順で注文することができます、あなたが知っているので、最初の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() 

、その後、偽の答え:

+1

ありがとうございました。コンセンサスがPHPでランダム化するように見えます。私はそれを行って、私がどのように乗っていくのか見ていきます。私が一度にすべての質問と回答を取得したい理由は、質問が一意でなければならないので、一度に1つずつ取得できないためです。彼らはテスト全体のためにユニークでなければなりません。希望は意味をなさない。 – SteveF

+1

最も簡単な解決策は、実際には1つのクエリで質問を取得してから、別のクエリで各質問の回答を取得することです。 –

1

はこれを試してみてください。これにより、PHPコードで1 + 3を簡単に選択できるようになります。

編集:私はあなたのグループを削除して、代わりに1行の回答を望むように並べます。

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