如果列Column_1
是独一无二的,我们可以这样做:
WHERE Column_1 > :last_retrieved_value
ORDER BY Column_1
LIMIT 20
从问题看来,Column_1
并不是唯一的,但是(Column_1,Column_2)
元组是唯一的。
“下一页”查询的一般形式,按这两列排序,使用这两列的最后检索到的值,将是......
(Column1,Column2) > (:lrv_col1,:lrv_col2)
(lrv = 从上一个查询检索到的最后一行保存的值)
要在 MySQL 中写入该条件,我们可以像您所示的那样执行此操作:
WHERE t.Column_1 > :lrv_col1
OR ( t.Column_1 = :lrv_col1 AND t.Column_2 > :lrv_col2 )
或者,我们可以这样写,我更喜欢这样,因为 MySQL 被 OR 条件混淆并使用错误索引的机会要小得多......
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
将其扩展到three列,检查条件...
(c1,c2,c3) > (:lrv1,:lrv2,:lrv3)
我们处理它就像处理两列一样,处理c1
首先,像两列一样将其分解:
WHERE c1 >= :lrv1
AND ( c1 > :lrv1 OR ( ... ) )
ORDER BY c1, c2, c3
LIMIT n
现在那个占位符...
(哪里会只检查c2
之前,实际上又只是两列的另一种情况。我们需要检查:(c2,c3) > (lrv2,lrv3)
,所以我们可以使用相同的模式扩展它:
WHERE c1 >= :lrv1
AND ( c1 > :lrv1 OR ( c2 >= :lrv2
AND ( c2 > :lrv2 OR c3 > :lrv3 )
)
)
ORDER BY c1,c2,c3
LIMIT n
我同意扩展可能看起来有点混乱。但它确实遵循一个非常有规律的模式。类似地,我们可以将条件表达为four列...
(c1,c2,c3,c4) > (:lrv1,:lrv2,:lrv3,:lrv4)
我们只需要三列,然后我们需要扩展c3 > :lrv3
替换为( 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
为了帮助未来的读者,我会评论这个块,并表明意图......
-- (c1,c2,c3,c4) > (lr1,lr2,lr3,lr4)
如果 MySQL 允许我们像这样表达比较,那就太好了。不幸的是,我们必须将其扩展为 MySQL 可以理解的东西。