Este es otro ejemplo de un TOP X registros por Y ejemplo. Para cada pregunta, quieres 4 respuestas. En realidad, se necesita un LÍMITE DOS VECES... Primero para limitar las preguntas de calificación, y otra "clasificación" de respuestas que garantiza que la respuesta "Correcta" SIEMPRE se incluya por conjunto de resultados de preguntas.
Así que mi enfoque es aplicar las preguntas aleatorias en contra primero para obtener eso como un resultado de subconjunto, luego unirlo a las respuestas y limitar X por Y. LUEGO, podemos terminarlo todo. Lo fundamental aquí es que la consulta interna debe ordenarse por el ID de la pregunta... Y el calificador de la respuesta "Correcta" siempre está en la primera posición, pero todo lo que sigue se aleatoriza para incluir un total de 4 registros.
Luego, la consulta final aplica la cláusula WHERE para incluir solo donde la secuencia de clasificación es <=4 (de las 9 respuestas posibles incluidas para 1 pregunta, pero luego aplica una cláusula final "ORDER BY" para mantener las preguntas juntas, pero aleatoriza las respuestas para que el "Correcto" ya no se devuelva siempre en la primera posición. Puede eliminar esta cláusula externa "ORDER BY" con fines de prueba solo para confirmar la funcionalidad y luego volver a agregarla más tarde.
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 par de pequeños cambios... Asegúrate de SQLVars
tiene :=
para cada una de las tareas. Cuando publiqué originalmente, dejé un ":" que podría haber arrojado un error falso. También califiqué el "Ordenar por" interno usando "a.correct =1" (no tenía referencia de alias). Finalmente, cambió la cláusula WHERE externa a solo < 5
en lugar de <= 4
. He hecho MUCHAS de estas grandes agrupaciones X por Y y sé que funcionan, solo me falta algo simple, estoy seguro.
Además, ajustó el IF()
aleatorio para tener el primer valor como un decimal, de lo contrario, todos los aleatorios se establecen en 1 (número entero) y nunca en fracciones ... También para posibles problemas de cuándo se aplica el ORDEN, he consultado previamente todas las preguntas y respuestas ordenadas previamente para obtener todas las respuestas correctas en la primera posición, ENTONCES aplique SQLVars
contra ese conjunto, luego finalice la secuencia de clasificación y el orden.