Postgres的胜利之路

时间:2018-08-08 09:42:30

标签: sql postgresql aggregate-functions gaps-and-islands

正如标题所述-我有一个Postgres数据库,其中包含球员和比赛,我想获得获奖名单。请注意,我不仅对数字感兴趣,也就是说,我在Stackoverflow上看到很多有关最高连胜的问题-我希望能够获得有关连胜的更多数据和细节,例如所有比赛。

具体地说,这是我正在查看的数据库: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
...       | ...      |  ...

“得分”是“玩家得分-对手得分”,所以我希望从同一位玩家获得正得分的条纹不间断。结果表如下所示:

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

这将允许我检索条纹的最后一场比赛,并且由于我知道条纹有多长时间,所以所有在条纹之前的比赛也是如此。是否有一种很好的方法来存储ID数组,以便我也可以存储行中条纹的所有相关matchID?也许在一个枚举中?

到目前为止,我所做的是按照球员ID /比赛ID的顺序对所有比赛进行Postgres视图,将其导出到Excel CSV,然后使用Excel公式+过滤器得出结果。当前看起来像this。但是,当然这并不是很容易更新,我很希望能够直接或至少部分地通过Query进行更新,或者甚至最好使用Aligulac API(http://aligulac.com/about/api/)。

关于如何按照这些思路做事的任何想法?谢谢!

1 个答案:

答案 0 :(得分:2)

使用两个窗口函数来指定系列和聚合函数以获得最长的条纹:

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)