Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Cursor-basierte Paginierung mit mehreren Spalten

Wenn (die leider benannte) Spalte Column_1 einzigartig ist, könnten Sie einfach Folgendes tun:

 WHERE Column_1 > :last_retrieved_value

Aus der Frage geht hervor, dass Column_1 ist nicht eindeutig, sondern der (Column_1,Column_2) Tupel ist eindeutig.

Die allgemeine Form für eine "nächste Seite"-Abfrage, die nach diesen beiden Spalten ordnet und die zuletzt abgerufenen Werte für diese beiden Spalten verwendet, wäre...

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

(lrv =gespeicherter Wert aus der letzten Zeile, die von der vorherigen Abfrage abgerufen wurde)

Um diese Bedingung in MySQL zu schreiben, können wir das so machen, wie Sie es gezeigt haben:

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

Oder wir könnten es so schreiben, was ich bevorzuge, weil es viel weniger Chancen für MySQL gibt, durch die OR-Bedingung verwirrt zu werden und den falschen Index zu verwenden...

 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

Um das auf drei zu erweitern Spalten, um den Zustand zu prüfen...

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

Wir behandeln es genauso wie im Fall von zwei Spalten, indem wir c1 behandeln Zuerst brechen Sie es genau wie die beiden Spalten auf:

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

Und jetzt dieser Platzhalter ... (wobei nur die Prüfung auf c2 gewesen wäre vorher, ist wirklich wieder nur ein weiterer Fall von zwei Spalten. Wir müssen überprüfen:(c2,c3) > (lrv2,lrv3) , also können wir das nach dem gleichen Muster erweitern:

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

Ich stimme zu, dass die Erweiterung ein wenig chaotisch aussehen kann. Aber es folgt einem sehr regelmäßigen Muster. Ebenso könnten wir die Bedingung auf vier ausdrücken Spalten...

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

Wir nehmen einfach das, was wir für die drei Spalten haben, und wir müssen c3 > :lrv3 erweitern um es durch ( c3 >= :lrv3 AND ( c3 > :lrv3 OR c4 > :lrv4 ) ) zu ersetzen

 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

Als Hilfestellung für zukünftige Leser würde ich diesen Block kommentieren und die Absicht angeben ...

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

Und es wäre schön, wenn MySQL uns erlauben würde, den Vergleich einfach so auszudrücken. Leider müssen wir das zu etwas erweitern, das MySQL versteht.