8.3 的问题rank()
是在 8.4 中引入的。
考虑数字 [10,6,6,2]。
我希望获得排名等于行号的那些数字的排名:
rank | score
-----+------
1 | 10
2 | 6
3 | 6
4 | 2
部分解决方案是自连接并计算得分更高或相等的项目。这会产生:
1 | 10
3 | 6
3 | 6
4 | 2
但这不是我想要的。
有没有办法排名,甚至只是按分数排序,然后提取该行号?
8.3 的问题rank()
是在 8.4 中引入的。
考虑数字 [10,6,6,2]。
我希望获得排名等于行号的那些数字的排名:
rank | score
-----+------
1 | 10
2 | 6
3 | 6
4 | 2
部分解决方案是自连接并计算得分更高或相等的项目。这会产生:
1 | 10
3 | 6
3 | 6
4 | 2
但这不是我想要的。
有没有办法排名,甚至只是按分数排序,然后提取该行号?
如果您想要一个与窗口函数等效的行号,您可以在 8.3 版(或任何版本)中使用 (temporary) 即兴创作:row_number()
SEQUENCE
CREATE TEMP SEQUENCE foo;
SELECT nextval('foo') AS rn, *
FROM (SELECT score FROM tbl ORDER BY score DESC) s;
子查询是在调用 之前nextval()
对行进行排序所必需的。
请注意,序列(像任何临时对象一样)...
要在每个查询之前重复运行同一会话中的序列:
SELECT setval('foo', 1, FALSE);
有一种方法使用适用于 PG 8.3 的数组。在性能方面,它可能不是很有效,但如果没有很多值,它就可以了。
这个想法是对临时数组中的值进行排序,然后提取数组的边界,然后将其连接起来generate_series
以一一提取值,数组的索引是行号。
假设表是示例查询scores(value int)
:
SELECT i AS row_number,arr[i] AS score
FROM (SELECT arr,generate_series(1,nb) AS i
FROM (SELECT arr,array_upper(arr,1) AS nb
FROM (SELECT array(SELECT value FROM scores ORDER BY value DESC) AS arr
) AS s2
) AS s1
) AS s0
你有这个表的PK吗?
只需自我加入并计算具有以下条件的项目:更高或相等的分数和更高的 PK。
PK 比较将打破平局并为您提供所需的结果。
升级到 9.1 后使用row_number()
.