我正在实现基于游标的分页。
要求是按任意条件(例如描述)对数据集进行排序,并逐行返回N
行X
(其中X
表示最后一页的最后一项)。
第一页很简单:
SELECT
id
FROM probe
ORDER BY description ASC
LIMIT 5
假设此查询返回 IDs 4, 5, 2, 1, 3
,那么下一个查询必须在id
3 之后从同一个查询中产生 5 个下一个结果。
注意:我们不能LIMIT ... OFFSET
在第一页之后使用,因为偏移量是相对于我们不知道的引用结果的位置。
我能想到解决这个问题的唯一方法是:
在数据集中查找 ID 3 的行号:
WITH
data_index AS (
SELECT
d1.*,
row_number() OVER () row_number
FROM (
SELECT
id
FROM probe
ORDER BY description ASC
) d1
)
SELECT
di1.row_number
FROM data_index di1
WHERE di1.id = 3;
然后使用位置来偏移数据集。
全部一起:
WITH
data_index AS (
SELECT
d1.*,
row_number() OVER () row_number
FROM (
SELECT
id
FROM probe
ORDER BY description ASC
) d1
)
SELECT
di1.id
FROM data_index di1
WHERE di1.row_number > (
SELECT
di1.row_number
FROM data_index di1
WHERE di1.id = 3
)
LIMIT 10;
这种方法的缺点是data_index
需要将整个子查询加载到内存中。有没有更有效的方法?
您可以简单地将用于排序 (
description
) 的列添加到SELECT
列表和WHERE
以下查询的子句中:让我们说你得到
@id = 3
并且@description = 'Beta'
作为最后(第5)行。然后,您可以使用这些值来获取下 (5) 行:如果您在之前订购结果,那么您必须通过与订单无关的时间
description
来获取下一部分。description
id