0

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

但这不是我想要的。
有没有办法排名,甚至只是按分数排序,然后提取该行号?

4

3 回答 3

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;

db<>fiddle here
sqlfiddle

子查询是在调用 之前nextval()对行进行排序所必需的。

请注意,序列(像任何临时对象一样)...

  • 仅在创建它的同一会话中可见。
  • 隐藏任何其他同名的表对象。
  • 在会话结束时自动删除。

要在每个查询之前重复运行同一会话中的序列:

SELECT setval('foo', 1, FALSE);
于 2013-01-25T16:57:59.217 回答
1

有一种方法使用适用于 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
于 2013-01-25T15:38:58.697 回答
0

你有这个表的PK吗?

只需自我加入并计算具有以下条件的项目:更高或相等的分数和更高的 PK

PK 比较将打破平局并为您提供所需的结果。

升级到 9.1 后使用row_number().

于 2013-01-25T14:04:12.187 回答