我有一个表格,希望能够显示“从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”的内容。
如果您想要排名,请执行以下操作
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。