Questo è un altro esempio di record TOP X per Y esempio. Per ogni domanda, vuoi 4 risposte. In realtà è necessario UN LIMITE DUE VOLTE... Prima per limitare le domande qualificanti e un'altra "classifica" di risposte che garantisca che la risposta "Corretta" sia SEMPRE inclusa per set di risultati delle domande.
Quindi il mio approccio consiste nell'applicare prima le domande casuali per ottenerlo come risultato di un sottoinsieme, quindi unirlo alle risposte e limitare X per Y. POI, possiamo concludere tutto. La cosa fondamentale qui è che la query interna deve essere ordinata in base all'ID della domanda... E il qualificatore la risposta "Corretta" è sempre in prima posizione, ma qualsiasi cosa dopo viene randomizzata per includere un totale di 4 record.
Quindi, la query finale applica la clausola WHERE per includere solo dove la sequenza di classificazione è <=4 (delle possibili tutte e 9 le risposte incluse per 1 domanda, ma poi applica una clausola finale "ORDER BY" per tenere insieme le domande, ma randomizza le risposte in modo che "Corretto" non venga più sempre restituito nella prima posizione. Puoi rimuovere questa clausola esterna "ORDER BY" a scopo di test solo per confermare la funzionalità, quindi aggiungerla di nuovo in un secondo momento.
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()
Un paio di piccole modifiche... Assicurati in SQLVars
ha :=
per ciascuno degli incarichi. Quando ho pubblicato originariamente, ho lasciato un ":" spento che avrebbe potuto generare un falso errore. Ho anche qualificato l'"Ordine per" interno usando "a.correct =1" (non aveva alcun riferimento alias). Infine, ho modificato la clausola WHERE esterna in solo < 5
invece di <= 4
. Ho creato MOLTI di questi migliori raggruppamenti X per Y e so che funzionano, mi manca solo qualcosa di semplice, ne sono sicuro.
Inoltre, regolato IF()
random per avere il primo valore come decimale, altrimenti tutti i random vengono impostati su 1 (numero intero) e mai su una frazione... Anche per possibili problemi di quando viene applicato ORDERING, ho pre-interrogato tutte le Q e A pre-ordinate per ottenere tutte le risposte corrette nella prima posizione, ALLORA applica SQLVars
rispetto a quel set, quindi finalizza la sequenza di classificazione e l'ordinamento.