row_number()带有未指定的窗口`row_number()OVER()`

时间:2013-10-25 19:23:45

标签: ruby-on-rails postgresql activerecord

我正在使用postgres 9.1构建一个分页记分板。

用户可以通过以下几个标准对记分板进行排序,并且可以按升序或降序排序。有一项功能可以让用户在记分板的多个页面中找到“他们的行”,并且必须反映用户选择的排序标准。

我正在使用postgres的row_number函数在结果集中找到它们的偏移量,以返回用户可以找到行的页面。

我正在阅读的关于row_number的所有内容似乎暗示坏事发生在未在row_number窗口中指定排序的人身上。例如。 row_number() OVER (ORDER BY score_1)没问题,row_number() OVER () 错误

我的情况与我读过的示例有所不同,因为我显式地命令我的查询,我意识到如果我不这样做,数据库引擎可能不会以任何特定的顺序返回结果。

但是我想在整个查询的级别指定排序并获取结果的row_number,而不必使用row_number的窗口复制我的排序规范。

所以这就是我想做的事情,而且“似乎有用”。

SELECT
  id, 
  row_number() OVER () AS player_position,
  score_1,
  score_2,
  score_3,
FROM my_table
ORDER BY (score_1 ASC | score_1 DESC | score_2 ASC | score_2 DESC | score_3 ASC | score_3 DESC)

player_position反映了我所订购的任何标准的球员排名。

但是我读过的文档告诉我,我应该这样做:

SELECT
  id, 
  row_number() OVER (ORDER BY score_1 ASC) AS player_position,
  score_1,
  score_2,
  score_3,
FROM my_table
ORDER BY score_1 ASC

SELECT
  id, 
  row_number() OVER (ORDER BY score_2 DESC) AS player_position,
  score_1,
  score_2,
  score_3,
FROM my_table
ORDER BY score_2 DESC

我想避免冗余地指定row_number窗口的顺序的真正原因是保持我的查询适用于ActiveRecord ORM。我希望得到我的基本记分牌查询,以及订购链。

e.g。最终,我希望能够做到这一点:

Players.scoreboard.order('score_1 ASC')
Players.scoreboard.order('score_2 DESC')
etc...

有可能吗?

1 个答案:

答案 0 :(得分:1)

尝试将主查询移动到带有ORDER BY的子查询中,并将ROW_NUMBER()应用于最外层的查询。

SELECT  y.*,
        ROW_NUMBER() OVER () as player_position
FROM
    (SELECT
        id, 
        score_1,
        score_2,
        score_3,
    FROM my_table
    ORDER BY <whatever>) as y