Mysql
 sql >> Base de données >  >> RDS >> Mysql

Pagination basée sur un curseur MySQL avec plusieurs colonnes

Si la colonne (malheureusement nommée) Column_1 est unique, vous pouvez simplement faire :

 WHERE Column_1 > :last_retrieved_value

D'après la question, il semble que Column_1 n'est pas unique, mais le (Column_1,Column_2) tuple est unique.

La forme générale d'une requête "page suivante", triée par ces deux colonnes, en utilisant les dernières valeurs récupérées pour ces deux colonnes, serait...

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

(lrv =valeur enregistrée de la dernière ligne récupérée par la requête précédente)

Pour écrire cette condition dans MySQL, nous pouvons le faire comme vous l'avez montré :

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

Ou, nous pourrions l'écrire comme ceci, ce que je préfère, car il y a beaucoup moins de chance que MySQL soit confus par la condition OR et utilise le mauvais index...

 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

Pour étendre cela à trois colonnes, pour vérifier l'état...

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

Nous le traitons comme dans le cas de deux colonnes, en manipulant c1 d'abord, décomposez-le comme les deux colonnes :

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

Et maintenant cet espace réservé ... (où aurait eu juste le chèque sur c2 avant, est vraiment à nouveau juste un autre cas de deux colonnes. Nous devons vérifier :(c2,c3) > (lrv2,lrv3) , nous pouvons donc développer cela en utilisant le même modèle :

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

Je suis d'accord que l'expansion peut sembler un peu désordonnée. Mais cela suit un schéma très régulier. De même, nous pourrions exprimer la condition sur quatre colonnes...

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

Nous prenons simplement ce que nous avons pour les trois colonnes, et nous devons développer c3 > :lrv3 pour le remplacer par ( 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

Pour aider le futur lecteur, je commenterais ce bloc, et indiquerais l'intention...

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

Et ce serait bien si MySQL nous permettait d'exprimer la comparaison comme ça. Malheureusement, nous devons étendre cela à quelque chose que MySQL comprend.