【问题标题】:Postgres PENULTIMATE LAST_VALUE() for cursor based paginationPostgres PENULTIMATE LAST_VALUE() 用于基于游标的分页
【发布时间】:2020-06-14 14:40:14
【问题描述】:

假设我有这张桌子:

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

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

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

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

所以我使用这个查询:

SELECT
    *
FROM
    "players"
  LIMIT 3

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

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

我可以使用类似下面的代码创建一个OVER ()(虚拟)列吗?

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

它可以工作,但 LAST_VALUE( ID ) 显示的是第三个 ID,而不是光标内容所需的第二个 ID。

有没有办法获得 PENULTIMATE LAST_VALUE ( ID )

【问题讨论】:

    标签: sql database postgresql pagination rows


    【解决方案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;
    

    请注意,没有ORDER BYLAST_VALUE() 返回一个任意 值。它可能看起来像是“最后一个值”,但这是巧合,不能保证。

    同样,LIMIT 没有ORDER BY 返回任意行。它可能看起来像前三个或后三个,但这是巧合,不能保证。

    像这样使用LAST_VALUE() 似乎很神秘。 . . MAX() 似乎更通俗一些:

    SELECT p.*,
           MAX ( ID ) OVER () AS lastvalue,
           NTH_VALUE(ID, 2) OVER (ORDER BY ID DESC) as penultimatevalue
    FROM "players" p
    LIMIT 3;
    

    【讨论】:

      猜你喜欢
      • 2017-05-20
      • 2018-10-06
      • 2016-10-27
      • 2019-06-29
      • 2021-12-27
      • 2021-06-03
      • 2021-07-18
      • 2021-04-09
      • 2018-11-30
      相关资源
      最近更新 更多