Implementing a total order ranking in PostgreSQL 8.3

后端 未结 3 976
既然无缘
既然无缘 2021-01-28 12:24

The issue with 8.3 is.....rank is introduced in 8.4.

consider the numbers [10,6,6,2]

I wish to achieve a rank of those numbers where the rank is equal to the th

相关标签:
3条回答
  • 2021-01-28 12:29

    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
    
    0 讨论(0)
  • 2021-01-28 12:45

    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().

    0 讨论(0)
  • 2021-01-28 12:46

    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);
    
    0 讨论(0)
提交回复
热议问题