sql – 计算每周锦标赛中的奖牌数量

我有一张桌子,每周都有几十名球员:

# select * from pref_money limit 5;
       id       | money |   yw
----------------+-------+---------
 OK32378280203  |   -27 | 2010-44
 OK274037315447 |   -56 | 2010-44
 OK19644992852  |     8 | 2010-44
 OK21807961329  |   114 | 2010-44
 FB1845091917   |   774 | 2010-44
(5 rows)

这个SQL语句让我获得每周获胜者以及每位玩家获胜的次数:

# select x.id, count(x.id) from (
    select id,
           row_number() over(partition by yw order by money desc) as ranking
    from pref_money
) x
where x.ranking = 1 group by x.id;
           id           | count
------------------------+-------
 OK9521784953           |     1
 OK356310219480         |     1
 MR797911753357391363   |     1
 OK135366127143         |     1
 OK314685454941         |     1
 OK308121034308         |     1
 OK4087658302           |     5
 OK452217781481         |     6
....

我想将后一个号码保存在球员牌桌的奖牌栏中:

# \d pref_users;
                   Table "public.pref_users"
   Column   |            Type             |     Modifiers
------------+-----------------------------+--------------------
 id         | character varying(32)       | not null
 first_name | character varying(64)       |
 last_name  | character varying(64)       |
 city       | character varying(64)       |
 medals     | integer                     | not null default 0

怎么办呢?我只能想到使用临时表,但必须有一个更简单的方法……谢谢

更新:

Clodoaldo建议的查询有效,但现在我的cronjob偶尔会失败:

/* reset and then update medals count */
update pref_users set medals = 0;
psql:/home/afarber/bin/clean-database.sql:63: ERROR:  deadlock detected
DETAIL:  Process 31072 waits for ShareLock on transaction 124735679; blocked by process 30368.
Process 30368 waits for ShareLock on transaction 124735675; blocked by process 31072.
HINT:  See server log for query details.

update pref_users u
set medals = s.medals
from (
    select id, count(id) medals
    from (
        select id,
            row_number() over(partition by yw order by money desc) as ranking
        from pref_money where yw <> to_char(CURRENT_TIMESTAMP, 'IYYY-IW')
    ) x
    where ranking = 1
    group by id
) s
where u.id = s.id;

最佳答案

update pref_users u
set medals = s.medals
from (
    select id, count(id) medals
    from (
        select id,
            row_number() over(partition by yw order by money desc) as ranking
        from pref_money
    ) x
    where ranking = 1
    group by id
) s
where u.id = s.id
点赞