To jest kolejny przykład rekordów TOP X na przykład Y. Na każde pytanie potrzebujesz 4 odpowiedzi. LIMIT jest faktycznie potrzebny DWUKROTNIE... Najpierw, aby ograniczyć pytania kwalifikujące, a kolejny „ranking” odpowiedzi, który gwarantuje, że „prawidłowa” odpowiedź na ZAWSZE zostanie uwzględniona w zestawie wyników pytania.
Więc moje podejście polega na tym, że najpierw zastosuję losowość do pytań, aby uzyskać wynik jako podzbiór, a następnie dopiszmy to do odpowiedzi i ograniczmy X na Y. WTEDY możemy to wszystko spakować. Najważniejszą rzeczą tutaj jest to, że wewnętrzne zapytanie musi być uporządkowane według identyfikatora pytania... ORAZ kwalifikator "Poprawna" odpowiedź jest zawsze na pierwszym miejscu, ale wszystko po jest losowane tak, aby zawierało w sumie 4 rekordy.
Następnie ostatnie zapytanie stosuje klauzulę WHERE, aby uwzględnić tylko te, w których kolejność rankingowa wynosi <=4 (z możliwych wszystkich 9 odpowiedzi zawartych dla 1 pytania, ale następnie stosuje końcową klauzulę „ORDER BY”, aby utrzymać pytania razem, ale losowo odpowiedzi, dzięki czemu „Poprawna” nie jest już zawsze zwracana na pierwszej pozycji. Możesz usunąć tę zewnętrzną klauzulę „ORDER BY” do celów testowych tylko w celu potwierdzenia funkcjonalności, a następnie dodać ją z powrotem później.
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()
Kilka małych zmian... Upewnij się, że w SQLVars
ma :=
dla każdego z zadań. Kiedy pierwotnie pisałem, zostawiłem jeden ":", który mógł spowodować fałszywy błąd. Określiłem również wewnętrzne „Zamówienie według” za pomocą „a.prawidłowy =1” (nie miałem odniesienia do aliasu). Na koniec zmieniono zewnętrzną klauzulę WHERE na < 5
zamiast <= 4
. Zrobiłem WIELE z tych najlepszych grupowań X na Y i wiem, że działają, ale jestem pewien, że brakuje mi czegoś prostego.
Ponadto dostosowano IF()
losowo, aby mieć pierwszą wartość jako ułamek dziesiętny, w przeciwnym razie wszystkie losy zostaną ustawione na 1 (liczba całkowita) i nigdy nie będą ułamkowe ... Również w przypadku możliwych problemów z zastosowaniem PORZĄDKOWANIA, wstępnie posortowałem wszystkie Q i A aby uzyskać wszystkie poprawne odpowiedzi na pierwszej pozycji, NASTĘPNIE zastosuj SQLVars
względem tego zestawu, a następnie sfinalizuj kolejność rang i kolejność.