PostgreSQL 中的行编号

发布于 2024-10-29 11:10:19 字数 606 浏览 4 评论 0原文

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

是否有其他方法可以返回有序和编号的结果,而无需复制代码?

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

How to get row number in PostgreSQL when the results are ordered by some column?

e.g.

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

I supposed that the query would return list like this:

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

Actually i have to duplicate the ORDER clause into the query to make it functional:

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

Is there any other way how to return ordered and numbered results without necessity of duplicating the code?

I know this can be solved by incrementing some variable in the app itself, but i wanna do this at the database layer and return to the app already numbered results...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

∞觅青森が 2024-11-05 11:10:19

否 - 窗口函数中的 order byselect 语句中的 order by 子句在功能上是两个不同的东西。

另外,您的语句会生成:错误:窗口函数调用需要 OVER 子句,因此:

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. 确保您订购的内容是唯一的

,否则可能会出现重复和丢失的行。请参阅 这个答案说明原因。

no - the order by in the windowing function and the order by clause of the select statement are functionally two different things.

Also, your statement produces: ERROR: window function call requires an OVER clause, so:

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

should be:

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

Note that if salaries are not unique then there is no guarantee that they will even produce the same order. Perhaps it would be better to do:

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

Also note that if you are running this query several times with different offsets, you need to:

  1. set your isolation level to serializable
  2. make sure that whatever you are ordering by is unique

or you may get duplicates and missing rows. See the comments on this answer for why.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文