Ini adalah contoh lain dari catatan TOP X per contoh Y. Untuk setiap pertanyaan, Anda menginginkan 4 jawaban. LIMIT sebenarnya diperlukan DUA KALI... Pertama untuk membatasi pertanyaan yang memenuhi syarat, dan "peringkat" jawaban lainnya yang menjamin jawaban "Benar" untuk SELALU disertakan per kumpulan hasil pertanyaan.
Jadi pendekatan saya adalah menerapkan acak terhadap pertanyaan terlebih dahulu untuk mendapatkan itu sebagai hasil bagian, lalu gabungkan itu ke jawaban dan batasi X per Y. KEMUDIAN, kita bisa menyelesaikan semuanya. Hal penting di sini adalah kueri dalam harus diurutkan berdasarkan ID pertanyaan... DAN kualifikasi jawaban "Benar" selalu berada di posisi pertama, tetapi apa pun setelahnya diacak untuk menyertakan total 4 catatan.
Kemudian, kueri terakhir menerapkan klausa WHERE untuk hanya menyertakan di mana urutan peringkatnya <=4 (dari kemungkinan semua 9 jawaban yang disertakan untuk 1 pertanyaan, tetapi kemudian menerapkan klausa "ORDER BY" terakhir untuk menyatukan pertanyaan, tetapi mengacak jawaban sehingga "Benar" tidak lagi selalu dikembalikan di posisi pertama. Anda dapat menghapus klausa luar "ORDER BY" ini untuk tujuan pengujian hanya untuk mengonfirmasi fungsionalitas, lalu menambahkannya kembali nanti.
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()
Beberapa perubahan kecil... Pastikan di SQLVars
memiliki :=
untuk masing-masing penugasan. Ketika saya awalnya memposting, saya meninggalkan satu ":" yang bisa menimbulkan kesalahan palsu. Saya juga mengkualifikasikan "Order by" bagian dalam dengan menggunakan "a.correct =1" (tidak memiliki referensi alias). Terakhir, ubah klausa WHERE luar menjadi < 5
bukannya <= 4
. Saya telah melakukan BANYAK pengelompokan X per Y terbaik ini dan tahu bahwa mereka berhasil, saya yakin hanya melewatkan sesuatu yang sederhana.
Juga, sesuaikan IF()
acak untuk memiliki nilai pertama sebagai desimal, jika tidak semua acak disetel ke 1 (bilangan bulat) dan tidak pernah pecahan... Juga untuk kemungkinan masalah ketika PEMESANAN diterapkan, saya telah menanyakan semua Q dan A yang telah diurutkan sebelumnya untuk mendapatkan semua jawaban yang benar di posisi pertama, MAKA terapkan SQLVars
terhadap set itu, lalu selesaikan urutan peringkat dan urutannya.