Postgres PENULTIMATE LAST_VALUE () для пагинации на основе курсора - PullRequest
0 голосов
/ 02 марта 2020

Допустим, у меня есть эта таблица:

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

Я пытаюсь разбить на страницы с помощью курсора (Relay / GraphQL).

Теперь, если пользователь запрашивает игроков из ID От 1 до 2 Мне нужен способ понять, есть ли в таблице больше игроков.

И я думаю, что можно использовать LIMIT 2 (последний запрошенный идентификатор) + 1 = 3.

Поэтому я использую этот запрос:

SELECT
    *
FROM
    "players"
  LIMIT 3

В своем внутреннем коде я удаляю последнюю строку и оцениваю hasNextPage как истинное и содержимое курсора (ID 2).

I ' я пытаюсь найти способ использовать SQL для выполнения этой тяжелой работы.

Могу ли я создать OVER () (виртуальный) столбец, используя что-то вроде приведенного ниже кода?

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

Это работает, но LAST_VALUE( ID ) показывает мне 3-й идентификатор, а не 2-й, который мне нужен для содержимого курсора.

Есть ли способ получить PENULTIMATE LAST_VALUE ( ID )?

1 Ответ

1 голос
/ 02 марта 2020

Вы можете использовать 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() без ORDER BY возвращает произвольное значение. Может показаться, что это «последнее значение», но это совпадение и не гарантируется.

Аналогично, 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;
...