sql >> Database >  >> RDS >> Mysql

mysql ingewikkelde sql

Dit is weer een voorbeeld van een TOP X records per Y voorbeeld. Voor elke vraag wil je 4 antwoorden. Een LIMIET is eigenlijk TWEE KEER nodig... Eerst om de kwalificerende vragen te beperken, en een andere "rangschikking" van antwoorden die garandeert dat het "juiste" antwoord ALTIJD wordt opgenomen per vraagresultaatset.

Dus mijn benadering is om eerst de random tegen vragen toe te passen om dat als een subsetresultaat te krijgen, dat dan samen te voegen met de antwoorden en X per Y te beperken. DAN kunnen we het allemaal inpakken. Het cruciale punt hier is dat de innerlijke query moet worden geordend op de vraag-ID... EN de kwalificatie het "Correcte" antwoord staat altijd op de eerste positie, maar alles daarna wordt willekeurig verdeeld om in totaal 4 records op te nemen.

Vervolgens past de laatste query de WHERE-clausule toe om alleen op te nemen waar de rangschikkingsvolgorde <=4 is (van de mogelijke alle 9 antwoorden voor 1 vraag, maar past dan een laatste "ORDER BY"-clausule toe om de vragen bij elkaar te houden, maar randomiseert de antwoorden zodat de "Correct" niet langer altijd op de eerste positie wordt geretourneerd. U kunt deze buitenste "ORDER BY"-clausule voor testdoeleinden verwijderen om de functionaliteit te bevestigen, en deze later weer toevoegen.

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

Paar kleine veranderingen... Zorg ervoor dat bij de SQLVars heeft := voor elk van de opdrachten. Toen ik oorspronkelijk postte, liet ik een ":" weg die een valse fout had kunnen veroorzaken. Ik heb ook de innerlijke "Order by" gekwalificeerd door "a.correct =1" te gebruiken (had geen aliasreferentie). Verander ten slotte de buitenste WHERE-clausule in slechts < 5 in plaats van <= 4 . Ik heb VEEL van deze geweldige X per Y-groeperingen gedaan en weet dat ze werken, alleen mis ik iets eenvoudigs, dat weet ik zeker.

Pas ook de IF() . aan willekeurig om de eerste waarde als decimaalteken te hebben, anders worden alle willekeurige getallen ingesteld op 1 (geheel getal) en nooit op breuken... Ook voor mogelijke problemen met het moment waarop de BESTELLING wordt toegepast, heb ik vooraf alle Q en A voorgesorteerd opgevraagd om alle juiste antwoorden op de eerste positie te krijgen, DAN pas de SQLVars . toe tegen die set, voltooi vervolgens de rangorde en rangschikking.



  1. Hoe gebruik ik een subquery voor dbtable-optie in de jdbc-gegevensbron?

  2. Is er een manier om power bi-rapporten en -dashboards in de vb.net- of C#-desktoptoepassing in te sluiten met de SQL Server 2008-database?

  3. SQL Server:Database zit vast in herstelstatus

  4. mysqli voorbereide instructie - werk NULL-waarden niet bij