在 Postgres 中的连胜纪录
Posted
技术标签:
【中文标题】在 Postgres 中的连胜纪录【英文标题】:Winning streaks in Postgres 【发布时间】:2018-08-08 09:42:29 【问题描述】:正如标题所说 - 我有一个包含球员和比赛的 Postgres 数据库,我想获得连胜记录的列表。请注意,我不仅对数字感兴趣,也就是说,我在 *** 上看到很多关于最高连胜的问题 - 我希望能够获得更多关于连胜的数据和详细信息,例如所有游戏。
具体来说,这是我正在查看的数据库: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 -对手score”,所以我想要来自同一玩家的连续正分数,而不会中断。结果表可能如下所示:
player_id | match_id | streak
-------------------------------
82 | 5363 | 5
51 | 5037 | 3
... | ... | ...
这将允许我检索连胜的最后一场比赛,因为我知道连胜的时间,所以我也知道连胜之前的所有比赛。有没有一种存储 ID 数组的好方法,以便我可以存储所有相关的 matchID,这些 matchID 也是行中连胜的一部分?也许在一个枚举左右?
到目前为止,我所做的是制作所有比赛的 Postgres 视图,按玩家 ID/比赛 ID 排序,将其导出到 Excel CSV,然后使用 Excel 公式 + 过滤器得出结果。目前看起来像this。但当然,这并不容易更新,我希望能够直接通过 Query 进行更新,或者至少是其中的一部分 - 或者更好地使用 Aligulac API (http://aligulac.com/about/api/)。
关于如何按照这些思路做某事的任何想法?谢谢!
【问题讨论】:
这里的大多数人都想要格式化的文本,而不是图像——甚至更糟——图像的链接。 听起来像是“差距和孤岛”问题。 对不起@jarlh - 不知道情况如此糟糕。这些不是图片链接,而是数据库链接和生成的 Google Sheets 表格以提供一些上下文。但我已经添加了抽象问题核心的表格,希望有助于使其更易于访问。感谢有关如何改进问题或潜在解决方案的任何其他建议。 在您看来,您需要一个定义行顺序的列,您无法在无序数据集上找到系列。该列可以是例如整数主键或时间戳/日期列(匹配日期),或类似的东西。 @klin 好点,没想到。创建视图时,我按“player_id,match_id”对其进行排序,然后将其导出到 Excel - 效果很好。比赛日期无关紧要,因为每个球员每天经常有很多比赛,所以 match_id 可能是一个更好的顺序。我可以只使用元组“player_id,match_id”吗?由于您无法将主键添加到 Postgres 视图。 【参考方案1】:使用两个窗口函数来指定序列和聚合函数以获得最长的连续:
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)
【讨论】:
非常感谢您提供此解决方案。我花了一段时间才找到时间来实现它,然后弄清楚它的作用,它是如何工作的,以及如何根据我的需要调整它(在我看来也发现了一个错误,所以这是一个痛苦但有帮助的练习)。我省略了“distinct”子句和最大值,因为我对所有连胜感兴趣,而不仅仅是每个球员的最佳连胜。但我想这在我的帖子中并不清楚,所以它在我身上,毕竟这一切都帮助我加深了对 Postgres 的理解。现在我可以用这个做很多有趣的事情。谢谢!以上是关于在 Postgres 中的连胜纪录的主要内容,如果未能解决你的问题,请参考以下文章