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

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

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

推荐答案

否-windowing函数中的order byselect语句中的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

还请注意,如果要使用不同的偏移量多次运行此查询,则需要:

  1. isolation level设置为可序列化
  2. 确保你点的东西都是独一无二的

或者,您可能会得到重复和丢失的行.请参阅this answer上的 comments 了解原因.

Postgresql相关问答推荐

一列引用两个不同的表

Postgres-pgloader-默认情况下,在PostgreSQL中将列名转换为小写

Rust中使用sqlx的多线程postgres操作的惯用方法是什么?

Postgres 对 WHERE 子句并行使用两个索引

使用Helm设置PostgreSQL配置

Upper() 不会大写重音字符

在 SQL 上返回负值

如何在 postgresql 中创建一个空的 JSON 对象?

如何获得区间的绝对值

是否有 postgres CLOSEST 运算符?

INSERT RETURNING 是否保证以 right的顺序返回?

带有 -C 选项的 pg_restore 不会创建数据库

如何将两个 PostgreSQL 列聚合到一个用括号分隔的数组

如何将1 天 01:30:00等间隔转换为25:30:00?

为什么 PostgreSQL 数组访问在 C 中比在 PL/pgSQL 中快得多?

PostgreSQL:将结果数据从 SQL 查询导出到 Excel/CSV

如何使用 Node.js 和 Postgresql 找到最后一个插入 ID?

由于外键约束无法删除对象

将数据推送到 Heroku 时出错:time zone displacement out of range

在 postgresql 中对使用 array_agg 创建的文本聚合进行排序