PostgreSQL排名查询

时间:2012-02-27 20:03:48

标签: sql postgresql

我正在尝试做类似于this的事情,但我需要通过公共字段进行分组的额外复杂性

我有两个表,一个用于competition_users(对于那些在比赛中竞争)和另一个competition_times(用于存储他们最快的时间),但在同一个表中有许多不同的比赛。

我在rank表中创建了一个新列competition_times,现在需要为现有用户运行更新以显示他们在竞争中的排名,我正在尝试修改在其他SO回答没有成功

表格如下......

competition_users:

competition_user_idcompetition_id

competition_times:

competition_time_idcompetition_user_idtime_in_secondsrank

我不确定是否可以使用GROUP BY?或者如果有另一种方式,到目前为止我正在尝试这样的事情......

UPDATE competition_times
SET    rank = r.rnk
FROM (
    SELECT competition_time_id
         , dense_rank() OVER (ORDER BY time_in_seconds ASC) AS rnk
    FROM competition_times, competition_users
    WHERE competition_times.competition_user_id = competition_users.competition_user_id
    GROUP BY competition_users.competition_id
    ) r
WHERE competition_times.competition_time_id = r.competition_time_id

使用postgreSQL 9

由于

1 个答案:

答案 0 :(得分:5)

你需要在窗口函数中使用PARTITION BY子句来保持比赛之间的排名。

UPDATE competition_times
SET    
    rank = r.rnk
FROM (
    SELECT competition_time_id, dense_rank() OVER (PARTITION BY competition_id ORDER BY time_in_seconds ASC) AS rnk
    FROM competition_times
    INNER JOIN competition_users
      ON competition_times.competition_user_id = competition_users.competition_user_id
    ) r
WHERE competition_times.competition_time_id = r.competition_time_id

以下示例数据:

create table competition_users
(competition_user_id  int, competition_id   int);

create table competition_times
(competition_time_id int, competition_user_id int, time_in_seconds int, rank int);

insert into competition_users values 
(1,1),(2,1),(3,1),(4,1),(5,2),(6,2);

insert into competition_times values 
(1,1,10,null),
(2,2,20,null),
(3,3,15,null),
(4,4,15,null),
(5,5,10,null),
(6,6,7,null);

我在竞争时间得到了结果:

competition_time_id competition_user_id time_in_seconds rank
1                   1                   10              1
2                   2                   20              3
3                   3                   15              2
4                   4                   15              2
5                   5                   10              2
6                   6                    7              1

第1-4行在一场比赛中,第5行和第6行在另一场比赛中。