Implementing a total order ranking in PostgreSQL 8.3

只谈情不闲聊 提交于 2019-12-02 07:48:57

If you want a row number equivalent to the window function row_number(), you can improvise in version 8.3 with a (temporary) SEQUENCE:

CREATE TEMP SEQUENCE foo;

SELECT nextval('foo') AS rn, *
FROM   (SELECT score FROM tbl ORDER BY score DESC) s

SQL Fiddle.
The subselect is necessary to order rows before calling nextval().

Note that the sequence (like any temporary object) ...

  • is only visible in the same session it was created.
  • hides any other table object of the same name.
  • is dropped automatically at the end of the session.

To use the sequence in the same session repeatedly run before each query:

SELECT setval('foo', 1, FALSE);

There's a method using an array that works with PG 8.3. It's probably not very efficient, performance-wise, but will do OK if there aren't a lot of values.

The idea is to sort the values in a temporary array, then extract the bounds of the array, then join that with generate_series to extract the values one by one, the index into the array being the row number.

Sample query assuming the table is 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

Do you have a PK for this table?

Just self join and count items with: a higher or equal score and higher PK.

PK comparison will break ties and give you desired result.

And after you upgrade to 9.1 - use row_number().

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!