Това е друг пример за ТОП X записи за Y пример. За всеки въпрос искате 4 отговора. ОГРАНИЧЕНИЕТО всъщност е необходимо ДВА пъти... Първо за ограничаване на квалифициращите въпроси и друго "класиране" на отговорите, което гарантира, че "правилният" отговор ВИНАГИ ще бъде включен за набор от резултати от въпроси.
Така че моят подход е първо да приложа произволното спрямо въпросите, за да го получа като резултат от подмножество, след това да го присъединя към отговорите и да огранича X на Y. СЛЕДА можем да приключим всичко. Най-важното тук е, че вътрешната заявка трябва да бъде подредена по идентификатора на въпроса... И квалификаторът „Верният“ отговор винаги е на първа позиция, но всичко след това се рандомизира, за да включва общо 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
има :=
за всяка една от задачите. Когато първоначално публикувах, оставих едно ":", което може да доведе до фалшива грешка. Също така квалифицирах вътрешната „Поръчай по“ с помощта на „a.correct =1“ (нямах препратка към псевдоним). Накрая промени външната клауза WHERE само на < 5
вместо <= 4
. Направих МНОГО от тези най-велики групи X на Y и знам, че работят, просто пропускам нещо просто, сигурен съм.
Също така коригирах IF()
random, за да има първа стойност като десетична, в противен случай всички произволни числа се задават на 1 (цяло число) и никога на дроб... Също така за възможни проблеми, когато се прилага ПОРЪЧВАНЕТО, направих предварително запитване за всички Q и A предварително сортирани за да получите всички правилни отговори на първа позиция, СЛЕД приложете SQLVars
спрямо този набор, след това финализирайте последователността на ранга и подреждането.