Postgres 的连胜记录

Winning streaks in Postgres

正如标题所说 - 我有一个包含球员和比赛的 Postgres 数据库,我想获得连胜记录。请注意,我不仅对数字感兴趣,也就是说,我在 Whosebug 上看到很多关于最高连胜的问题——我希望能够获得更多关于连胜的数据和详细信息,例如所有比赛。

具体来说,这是我正在查看的数据库:http://aligulac.com/about/db/。我基于此创建了一个具有基本列的视图,基本上如下所示:

player_id | match_id | score
-------------------------------
82        | 2847     |  2
82        | 3733     |  3
82        | 4348     |  1
82        | 5237     |  1
82        | 5363     |  3
82        | 7274     | -1
51        | 2347     |  3
51        | 3746     |  2
51        | 5037     |  3
51        | 7269     | -1
...       | ...      |  ...

"score" 是 "player_score - opponent_score",所以我希望同一位玩家的连续得分不间断。结果 table 可能如下所示:

player_id | match_id | streak
-------------------------------
82        | 5363     |  5
51        | 5037     |  3
...       | ...      |  ...

这将使我能够检索连续上场比赛的最后一场比赛,并且因为我知道连续比赛有多长,所以我也知道连续上场比赛之前的所有比赛。有没有一种存储 ID 数组的好方法,这样我就可以存储所有相关的 matchID,这些匹配 ID 也是该行中连胜的一部分?也许在枚举中?

到目前为止我所做的是制作所有比赛的 Postgres 视图,按玩家 ID/match ID 排序,将其导出到 Excel CSV,然后使用 Excel 公式+ 过滤器以得出结果。看起来像 this currently. But of course that's not really easy to update and I'd love to be able to do it via Query directly, or at least part of it - or even better using the Aligulac API (http://aligulac.com/about/api/).

关于如何按照这些思路做某事有什么想法吗?谢谢!

使用两个window函数来指定系列和聚合函数以获得最长的连胜:

select distinct on (player_id)
    player_id, 
    max(match_id) as match_id, 
    count(*) as streak
from (
    select 
        player_id, match_id, score, 
        sum(grp) over w as grp
    from (
        select 
            player_id, match_id, score, 
            (score < 0 and lag(score, 1, 1) over w > 0)::int as grp
        from my_view
        window w as (partition by player_id order by match_id)
        ) s
    window w as (partition by player_id order by match_id)
    ) s
where score > 0
group by player_id, grp
order by player_id desc, streak desc

 player_id | match_id | streak 
-----------+----------+--------
        82 |     5363 |      5
        51 |     5037 |      3
(2 rows)