sql >> Databasteknik >  >> RDS >> Mysql

mysql komplicerad sql

Detta är ytterligare ett exempel på TOP X-poster per Y-exempel. För varje fråga vill du ha 4 svar. EN LIMIT behövs faktiskt TVÅ GANGER... Först för att begränsa de kvalificerande frågorna, och ytterligare en "rankning" av svar som garanterar att det "korrekta" svaret ALLTID inkluderas per frågeresultatuppsättning.

Så mitt tillvägagångssätt är att först tillämpa slumpmässiga frågor mot frågor för att få det som ett delmängdsresultat, sedan sammanfoga det till svaren och begränsa X per Y. DÅ kan vi få det hela klart. Det kritiska här är att den inre frågan måste sorteras efter fråge-ID... OCH kvalificeraren, det "korrekta" svaret är alltid på första plats, men allt efter slumpas till att inkludera totalt 4 poster.

Sedan tillämpar den sista frågan WHERE-satsen för att bara inkludera där rankningssekvensen är <=4 (av de möjliga alla 9 svaren som ingår för 1 fråga, men tillämpar sedan en sista "ORDER BY"-sats för att hålla frågorna samman, men slumpmässigt svaren så att "Rätt" inte längre alltid returneras i den första positionen. Du kan ta bort den här yttre "ORDER BY"-satsen för teständamål bara för att bekräfta funktionaliteten och sedan lägga till den igen senare.

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()

Ett par små ändringar... Se till vid SQLVars har := för vart och ett av uppdragen. När jag ursprungligen postade lämnade jag ett ":" av vilket kunde ha orsakat ett falskt fel. Jag kvalificerade också den inre "Order by" genom att använda "a.correct =1" (hade ingen aliasreferens). Ändrade slutligen den yttre WHERE-satsen till bara < 5 istället för <= 4 . Jag har gjort MÅNGA av dessa bästa X per Y-grupperingar och vet att de fungerar, jag är säker på att jag bara saknar något enkelt.

Justerade även IF() slumpmässigt för att ha första värdet som en decimal, annars sätts alla slumpmässiga till 1 (heltal) och aldrig bråktal... Även för möjliga problem med när BESTÄLLNING tillämpas, har jag förfrågat alla F och A försorterade för att få alla korrekta svar i första positionen, använd DÅ SQLVars mot den uppsättningen, slutför sedan rangordningen och ordningen.



  1. Infoga och välja UUID som binär(16)

  2. Ta bort MariaDB eller MySQL helt från CentOS 7 eller RHEL 7

  3. Hämtar rader tillagda förra timmen

  4. laravel som har:Kolumn hittades inte