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

MySQL cursor baseret paginering med flere kolonner

If (den uheldigvis navngivne) kolonne Column_1 er unik, kan du bare gøre:

 WHERE Column_1 > :last_retrieved_value

Af spørgsmålet fremgår det, at Column_1 er ikke unik, men (Column_1,Column_2) tuple er unik.

Den generelle formular for en "næste side"-forespørgsel, sorteret efter disse to kolonner, ved hjælp af de sidst hentede værdier for disse to kolonner, ville være...

    (Column1,Column2) > (:lrv_col1,:lrv_col2)

(lrv =værdi gemt fra den sidste række hentet af den forrige forespørgsel)

For at skrive denne betingelse i MySQL, kan vi gøre det, som du har vist:

 WHERE t.Column_1 > :lrv_col1
    OR ( t.Column_1 = :lrv_col1 AND t.Column_2 > :lrv_col2 )

Eller vi kunne skrive det sådan, som jeg foretrækker, fordi der er meget mindre chance for, at MySQL bliver forvirret af OR-tilstanden og bruger det forkerte indeks...

 WHERE t.Column_1 >= :lrv_col1
       AND ( t.Column_1 > :lrv_col1 OR t.Column_2 > :lrv_col2 )
 ORDER BY t.Column_1, t.Column_2
 LIMIT n

For at udvide det til tre kolonner for at kontrollere tilstanden...

  (c1,c2,c3) > (:lrv1,:lrv2,:lrv3)

Vi håndterer det ligesom i tilfældet med to kolonner, hvor vi håndterer c1 først, bryde det ud ligesom de to kolonner:

 WHERE c1 >= :lrv1
       AND ( c1 > :lrv1 OR ( ... ) )
 ORDER BY c1, c2, c3
 LIMIT n

Og nu den pladsholder ... (hvor ville kun have haft tjek på c2 før, er egentlig igen bare endnu et tilfælde af to kolonner. Vi skal kontrollere:(c2,c3) > (lrv2,lrv3) , så vi kan udvide det ved at bruge det samme mønster:

 WHERE c1 >= :lrv1
       AND ( c1 > :lrv1 OR ( c2 >= :lrv2 
                             AND ( c2 > :lrv2 OR c3 > :lrv3 )
                           )
           )
 ORDER BY c1,c2,c3
 LIMIT n

Jeg er enig i, at udvidelsen kan se lidt rodet ud. Men det følger et meget regelmæssigt mønster. På samme måde kunne vi udtrykke betingelsen på fire kolonner...

 (c1,c2,c3,c4) > (:lrv1,:lrv2,:lrv3,:lrv4)

Vi tager bare det, vi har for de tre kolonner, og vi skal udvide c3 > :lrv3 for at erstatte det med ( c3 >= :lrv3 AND ( c3 > :lrv3 OR c4 > :lrv4 ) )

 WHERE c1 >= :lrv1
       AND ( c1 > :lrv1 OR ( c2 >= :lrv2 
                             AND ( c2 > :lrv2 OR ( c3 >= :lrv3
                                                   AND ( c3 > :lrv3 OR c4 > :lrv4 )
                                                 )
                                 )
                           )
           )
 ORDER BY c1,c2,c3,c4
 LIMIT n

Som en hjælp for den fremtidige læser vil jeg kommentere denne blok og angive hensigten ...

 -- (c1,c2,c3,c4) > (lr1,lr2,lr3,lr4)

Og det ville være rart, hvis MySQL ville tillade os at udtrykke sammenligningen sådan. Desværre er vi nødt til at udvide det til noget MySQL forstår.




  1. Hvordan opdateres samme tabel ved sletning i MYSQL?

  2. Udførelse af en LIKE-sammenligning på et INT-felt

  3. Sådan sorteres rækker af HTML-tabel, der kaldes fra MySQL

  4. Sådan fungerer TRY_CAST() i SQL Server