小编典典

我应该如何处理PostgreSQL中的y中的“ x个x”数据?

sql

我有一个表格,希望能够显示“从Y到X排名”的数据。特别是,我希望能够以一种相对有效的方式(即不选择表中的每一行)来显示单个行的数据。排名本身很简单,它是对表中单列的直接ORDER
BY。

在这方面,Postgres似乎提出了一些独特的挑战。AFAICT它没有RANK或ROW_NUMBER或同等功能(至少在8.3中,我暂时停留在此位置)。邮件列表档案中的规范答案似乎是创建一个临时序列并从中选择:

test=> create temporary sequence tmp_seq;
CREATE SEQUENCE
test=*> select nextval('tmp_seq') as row_number, col1, col2 from foo;

当我只想从表中选择一行(并且我想按PK而不是按等级选择)时,此解决方案似乎仍然无济于事。

我可以对等级进行非规范化并将其存储在单独的列中,这使得呈现数据的难度很小,但是只是重新定位了我的问题。UPDATE不支持ORDER
BY,因此我不确定如何构造UPDATE查询来设置等级(缺少选择每一行并为每一行运行单独的UPDATE的方法,这似乎使DB活动过多每次需要更新排名时触发)。

我缺少明显的东西吗?什么是正确的方法?

编辑 :显然我还不够清楚。我知道OFFSET /
LIMIT,但我看不到它如何帮助解决此问题。我不是要选择排名第X的项目,而是要选择一个任意项(例如,按其PK),然后向用户显示类似“
312中排名第43”的内容。


阅读 207

收藏
2021-03-23

共1个答案

小编典典

如果您想要排名,请执行以下操作

SELECT id,num,rank FROM (
  SELECT id,num,rank() OVER (ORDER BY num) FROM foo
) AS bar WHERE id=4

或者,如果您确实想要行号,请使用

SELECT id,num,row_number FROM (
  SELECT id,num,row_number() OVER (ORDER BY num) FROM foo
) AS bar WHERE id=4

当您在某处具有相等的值时,它们将有所不同。如果需要的话,也有density_rank()。

当然,这需要PostgreSQL 8.4。

2021-03-23