27

当结果按某列排序时,如何在 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

有没有其他方法可以在不需要复制代码的情况下返回有序和编号的结果?

我知道这可以通过在应用程序本身中增加一些变量来解决,但我想在数据库层执行此操作并返回应用程序已经编号的结果......

4

1 回答 1

37

否 -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. 确保您订购的任何商品都是独一无二的

或者你可能会得到重复和缺失的行。请参阅对此答案的评论以了解原因。

于 2011-04-04T11:19:31.150 回答