Als (de helaas genoemde) kolom Column_1
is uniek, je zou gewoon kunnen doen:
WHERE Column_1 > :last_retrieved_value
Uit de vraag blijkt dat Column_1
is niet uniek, maar de (Column_1,Column_2)
tuple is uniek.
De algemene vorm voor een "volgende pagina"-query, geordend op die twee kolommen, waarbij de laatst opgehaalde waarden voor die twee kolommen worden gebruikt, zou zijn...
(Column1,Column2) > (:lrv_col1,:lrv_col2)
(lrv =waarde opgeslagen van de laatste rij die is opgehaald door de vorige zoekopdracht)
Om die voorwaarde in MySQL te schrijven, kunnen we dat doen zoals je hebt laten zien:
WHERE t.Column_1 > :lrv_col1
OR ( t.Column_1 = :lrv_col1 AND t.Column_2 > :lrv_col2 )
Of we kunnen het zo schrijven, wat mijn voorkeur heeft, omdat MySQL veel minder kans heeft om in de war te raken door de OR-voorwaarde en de verkeerde index te gebruiken...
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
Om dat uit te breiden tot drie kolommen, om de voorwaarde te controleren...
(c1,c2,c3) > (:lrv1,:lrv2,:lrv3)
We behandelen het net als in het geval van twee kolommen, met c1
eerst uitsplitsen, net als de twee kolommen:
WHERE c1 >= :lrv1
AND ( c1 > :lrv1 OR ( ... ) )
ORDER BY c1, c2, c3
LIMIT n
En nu die tijdelijke aanduiding ...
(waar zou alleen de controle op c2
zijn geweest voorheen, is eigenlijk weer gewoon een ander geval van twee kolommen. We moeten controleren:(c2,c3) > (lrv2,lrv3)
, zodat we dat kunnen uitbreiden met hetzelfde patroon:
WHERE c1 >= :lrv1
AND ( c1 > :lrv1 OR ( c2 >= :lrv2
AND ( c2 > :lrv2 OR c3 > :lrv3 )
)
)
ORDER BY c1,c2,c3
LIMIT n
Ik ben het ermee eens dat de uitbreiding er misschien een beetje rommelig uitziet. Maar het volgt wel een heel regelmatig patroon. Op dezelfde manier kunnen we de voorwaarde uitdrukken op vier kolommen...
(c1,c2,c3,c4) > (:lrv1,:lrv2,:lrv3,:lrv4)
We nemen gewoon wat we hebben voor de drie kolommen, en we moeten c3 > :lrv3
uitbreiden om het te vervangen door ( 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
Als hulpmiddel voor de toekomstige lezer zou ik commentaar geven op dit blok en de bedoeling aangeven ...
-- (c1,c2,c3,c4) > (lr1,lr2,lr3,lr4)
En het zou mooi zijn als MySQL ons in staat zou stellen om de vergelijking zomaar uit te drukken. Helaas moeten we dat uitbreiden naar iets dat MySQL begrijpt.