PostgreSQL 中的行编号
Posted
技术标签:
【中文标题】PostgreSQL 中的行编号【英文标题】:Row numbering in PostgreSQL 【发布时间】:2011-07-29 02:16:25 【问题描述】:当结果按某列排序时,如何在 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】:否 - 窗口函数中的 order by
和 select
语句的 order by
子句在功能上是两个不同的东西。
另外,你的语句产生: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
另外请注意,如果您使用不同的偏移量多次运行此查询,您需要:
-
将您的 isolation level 设置为可序列化
确保您订购的商品是独一无二的
否则您可能会得到重复和丢失的行。请参阅this answer 上的 cmets 了解原因。
【讨论】:
“隔离级别可重复读取”是所有必要的......但无论哪种方式,您都需要确保连接和事务保持打开......这可能很难做到,具体取决于应用程序.以上是关于PostgreSQL 中的行编号的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQ 连接问题 FATAL: no pg_hba.conf entry for host