PostgreSQL中的行编号

时间:2011-04-04 11:01:05

标签: postgresql row-number

如果按某些列排序结果,如何在PostgreSQL中获取行号?

e.g。

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 个答案:

答案 0 :(得分:37)

不 - 窗口函数中的order byorder 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. 将您的isolation level设置为可序列化
  2. 确保您订购的任何内容都是唯一的
  3. 或者您可能会遇到重复和丢失的行。有关原因,请参阅this answer上的评论。