यह प्रति Y उदाहरण में TOP X रिकॉर्ड का एक और उदाहरण है। प्रत्येक प्रश्न के लिए आपको 4 उत्तर चाहिए। एक LIMIT की वास्तव में दो बार आवश्यकता होती है... पहले क्वालीफाइंग प्रश्नों को सीमित करने के लिए, और उत्तरों की एक और "रैंकिंग" जो हमेशा "सही" उत्तर की गारंटी देता है, प्रति प्रश्न परिणाम सेट में शामिल किया जाना चाहिए।
तो मेरा दृष्टिकोण यह है कि पहले प्रश्नों के विरुद्ध यादृच्छिक को लागू करें ताकि इसे सबसेट परिणाम के रूप में प्राप्त किया जा सके, फिर उत्तर में शामिल हों और एक्स प्रति वाई को सीमित करें। फिर, हम इसे पूरी तरह से लपेट सकते हैं। यहां महत्वपूर्ण बात यह है कि आंतरिक क्वेरी को प्रश्न आईडी द्वारा आदेश दिया जाना है ... और क्वालीफायर "सही" उत्तर हमेशा पहले स्थान पर होता है, लेकिन इसके बाद कुछ भी यादृच्छिक होता है जिसमें कुल 4 रिकॉर्ड शामिल होते हैं।
फिर, अंतिम क्वेरी WHERE क्लॉज को केवल उस स्थान पर लागू करती है जहां रैंकिंग अनुक्रम <=4 है (संभावित सभी 9 उत्तरों में से 1 प्रश्न के लिए शामिल है, लेकिन फिर प्रश्नों को एक साथ रखने के लिए अंतिम "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" (कोई उपनाम संदर्भ नहीं था) का उपयोग करके आंतरिक "ऑर्डर बाय" भी योग्यता प्राप्त की। अंत में, बाहरी WHERE क्लॉज को केवल < 5
. में बदल दिया <= 4
. के बजाय . मैंने इन महानतम X प्रति Y समूहों में से कई किए हैं और जानते हैं कि वे काम करते हैं, बस कुछ आसान याद आ रहा है मुझे यकीन है।
साथ ही, IF()
. को एडजस्ट किया दशमलव के रूप में पहला मान रखने के लिए यादृच्छिक, अन्यथा सभी रैंडम 1 (पूर्ण संख्या) पर सेट हो जाते हैं और कभी भी भिन्न नहीं होते हैं ... इसके अलावा जब ऑर्डरिंग लागू किया जाता है, तो मैंने सभी क्यू और ए को पूर्व-सॉर्ट किया है पहली स्थिति में सभी सही उत्तर प्राप्त करने के लिए, फिर SQLVars
. लागू करें उस सेट के खिलाफ, फिर रैंक अनुक्रम और क्रम को अंतिम रूप दें।