Нумерация строк в PostgreSQL - PullRequest
27 голосов
/ 04 апреля 2011

Как получить номер строки в PostgreSQL, когда результаты упорядочены по какому-либо столбцу?

например,

SELECT 30+row_number() AS position, * 
FROM users 
ORDER BY salary DESC 
LIMIT 30 
OFFSET 30

Я предполагал, что запрос выдаст список, подобный этому:

position | name | salary
31       | Joy  | 4500
32       | Katie| 4000
33       | Frank| 3500

На самом деле мне нужно продублировать предложение ORDER в запросе, чтобы сделать его функциональным:

SELECT 30+row_number(ORDER BY salary DESC) AS position, * 
FROM users 
ORDER BY salary DESC 
LIMIT 30 
OFFSET 30

Есть ли другой способ вернуть упорядоченные и пронумерованные результаты без необходимости дублирования кода?

Я знаю, что это можно решить путем увеличения некоторой переменной в самом приложении, но я хочу сделать это на уровне базы данных и вернуть приложению уже пронумерованные результаты ...

1 Ответ

37 голосов
/ 04 апреля 2011

no - order by в оконной функции и предложение order by оператора select являются функционально двумя разными вещами.

Кроме того, ваше утверждение выдает: ERROR: window function call requires an OVER clause, поэтому:

SELECT 30+row_number(ORDER BY salary DESC) AS position, * FROM users ORDER BY salary DESC LIMIT 30 OFFSET 30

должно быть:

SELECT 30+row_number() OVER(ORDER BY salary DESC) AS position, * FROM users ORDER BY salary DESC LIMIT 30 OFFSET 30

Обратите внимание, что если зарплаты не являются уникальными, то нетгарантировать, что они будут даже производить тот же заказ.Возможно, было бы лучше сделать:

SELECT * 
FROM ( SELECT 30+row_number() OVER(ORDER BY salary DESC) AS position, * 
       FROM users )
ORDER BY position LIMIT 30 OFFSET 30

Также обратите внимание, что если вы выполняете этот запрос несколько раз с разными смещениями, вам необходимо:

  1. установить уровень изоляции до сериализуемого
  2. убедитесь, что все, что вы заказываете, является уникальным

, иначе вы можете получить дубликаты и пропущенные строки.См. Комментарии к этому ответу , почему

...