Это еще один пример записей TOP 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
имеет :=
для каждого из заданий. Когда я изначально был отправлен, я оставил одно сообщение «:», которое могло вызвать ложную ошибку. Я также квалифицировал внутренний «Order by», используя «a.correct = 1» (не имел ссылки на псевдоним). Наконец, изменилось внешнее предложение WHERE только на < 5
вместо <= 4
. Я много сделал из этих величайших X на группы Y и знаю, что они работают, просто пропуская что-то простое, я уверен.
Кроме того, скорректировано случайное значение IF()
, чтобы иметь первое значение как десятичное значение, в противном случае все randoms будут установлены в 1 (целое число) и никогда не будут делиться ... Также для возможных проблем, когда применяется ЗАКАЗ, -подтвердите все Q и A, предварительно отсортированные, чтобы получить все правильные ответы в первой позиции, затем примените SQLVars
к этому набору, затем завершите последовательность рангов и порядок.
Я попытался выполнить ваш другой вопрос, но так и не смог получить рабочее решение. Вот насколько я добрался, если другие захотят обратиться за помощью: http://www.sqlfiddle.com/#!2/34906/34. По какой-то причине «ORDER BY RAND()» во внутреннем запросе «ответов» не работает. – mellamokb
Вы бы лучше в PHP. У MySQL нет языковых конструкций, которые вы можете использовать в Oracle/SQL Server/PostgreSQL. – gbn
@gbn: Я согласен, тем более, что на вопрос только до 9 ответов. Так же легко вытащить все ответы на PHP и сделать рандомизацию там. – mellamokb