sql >> Database teknologi >  >> RDS >> Mysql

mysql kompliceret sql

Dette er endnu et eksempel på TOP X-poster pr. Y-eksempel. For hvert spørgsmål vil du have 4 svar. En LIMIT er faktisk nødvendig TO GANGE... Først for at begrænse de kvalificerende spørgsmål, og endnu en "rangering" af svar, som garanterer, at det "korrekte" svar ALTID inkluderes pr. spørgsmålsresultatsæt.

Så min tilgang er at anvende det tilfældige mod spørgsmål først for at få det som et undersætresultat, derefter slutte det til svarene og begrænse X pr. Y. SÅ kan vi få det hele afsluttet. Det kritiske her er, at den indre forespørgsel skal sorteres efter spørgsmåls-id'et... OG kvalifikationen, det "korrekte" svar er altid i første position, men alt efter er randomiseret til at inkludere i alt 4 poster.

Derefter anvender den sidste forespørgsel WHERE-klausulen til kun at inkludere, hvor rangeringssekvensen er <=4 (af de mulige alle 9 svar inkluderet for 1 spørgsmål, men anvender derefter en sidste "ORDER BY"-klausul for at holde spørgsmålene sammen, men randomiserer svarene, så det "korrekte" ikke længere altid returneres i den første position. Du kan fjerne denne ydre "ORDER BY"-klausul til testformål bare for at bekræfte funktionaliteten, og derefter tilføje den igen senere.

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

Et par små ændringer... Sørg for ved SQLVars har := for hver af opgaverne. Da jeg oprindeligt postede, efterlod jeg et ":" fra, hvilket kunne have givet en falsk fejl. Jeg kvalificerede også det indre "Bestil efter" ved at bruge "a.correct =1" (havde ingen aliasreference). Til sidst ændrede den ydre WHERE-sætning til kun < 5 i stedet for <= 4 . Jeg har lavet MANGE af disse bedste X-per-Y-grupperinger og ved, at de virker, jeg mangler bare noget simpelt.

Justerede også IF() tilfældig for at have første værdi som en decimal, ellers bliver alle tilfældige angivet til 1 (helt tal) og aldrig brøk... Også for mulige problemer med, hvornår BESTILLINGEN anvendes, har jeg forudsorteret alle Q og A på forhånd for at få alle korrekte svar i den første position, skal du SÅ anvende SQLVars mod det sæt, og afslut derefter rækkefølgen og rækkefølgen.



  1. Proaktiv PostgreSQL-overvågning (udviklerstudie/rådgivervinkel)

  2. Udvikling af de nye Microsoft SQL Server ODBC- og OLEDB-drivere

  3. Fremme ydeevne i en hybrid cloud-opsætning

  4. sql slette alle rækker ældre end 30 dage