Postgres PENULTIMATE LAST_VALUE()用于基于光标的分页

时间:2020-03-02 10:06:19

标签: sql database postgresql pagination rows

假设我有这张桌子:

+--------+----------+
| ID     | Name     |
+--------+----------+
| 1      | John     |
+--------+----------+
| 2      | Mike     |
+--------+----------+
| 3      | Bob      |
+--------+----------+

我正在尝试使用游标方法(Relay / GraphQL)进行分页。

现在,如果用户要求ID为1到2的玩家,我需要一种方法来了解表中是否还有更多玩家。

我认为一种方法是使用LIMIT 2(请求的最后一个ID)+1 = 3。

所以我使用以下查询:

SELECT
    *
FROM
    "players"
  LIMIT 3

在我的后端代码中,我删除最后一行并评估hasNextPage为真实和光标内容(ID 2)。

我正在尝试找到一种使用SQL来完成这项繁重工作的方法。

我可以使用以下代码创建OVER ()(虚拟)列吗?

SELECT
    *,
    LAST_VALUE ( ID ) OVER ( ) AS pageInfo
FROM
    "players"
  LIMIT 3

它可以工作,但是LAST_VALUE( ID )告诉我第三个ID,而不是光标内容需要的第二个。

是否可以获取PENULTIMATE LAST_VALUE ( ID )

1 个答案:

答案 0 :(得分:1)

您可以使用nth_value()

SELECT p.*,
       LAST_VALUE ( ID ) OVER ( ORDER BY ID ) AS pageInfo,
       NTH_VALUE(ID, 2) OVER (ORDER BY ID DESC) as page_Info_penultimate
FROM "players" p
LIMIT 3;

请注意,没有LAST_VALUE()的{​​{1}}返回一个任意值。看起来好像是“最后一个值”,但这只是巧合,不能保证。

类似地,没有ORDER BY的{​​{1}}返回任意行。它可能看起来像前三个或最后三个,但这只是巧合,不能保证。

像这样使用LIMIT似乎很不可思议。 。 。 ORDER BY似乎更口语化:

LAST_VALUE()