查找导致事件的行并将它们视为一个序列
Posted
技术标签:
【中文标题】查找导致事件的行并将它们视为一个序列【英文标题】:Finding the rows leading up to an event and treating them as a sequence 【发布时间】:2017-07-27 01:47:29 【问题描述】:这感觉像是一个间隙和孤岛问题,窗口函数似乎是正确的工具,但我似乎无法获得有效的结果。
我的数据如下所示(注意:GameID 是一个 UUID,为了便于阅读,此处显示为计数器):
GameID User Date Win
100 A 10/11/2012 0
101 A 10/12/2012 0
102 B 10/11/2012 0
103 B 10/13/2012 1
104 B 10/14/2012 0
105 C 10/10/2012 0
106 C 10/12/2012 0
107 C 10/13/2012 1
108 C 10/14/2012 0
109 C 10/15/2012 0
110 C 10/16/2012 0
111 C 10/17/2012 1
112 D 10/11/2012 0
113 D 10/13/2012 1
114 D 10/20/2012 0
115 D 10/21/2012 0
我希望捕获(计数/汇总到数组中)用户在每次获胜之前的损失序列。因此,例如,如果您查看用户 B,他们赢了一场,那场胜利之前输了一场。如果你看用户 C,ID 为 107 的胜利之前是两次失败,而 ID 为 111 的胜利之前是三次失败。
我希望应用数组聚合array_agg
并将前面的失败附加到胜利中。最终我想要以下结果:
GameID User Date Win LosingStreak
103 B 10/13/2012 1 [102]
107 C 10/13/2012 1 [105, 106]
111 C 10/17/2012 1 [110,109,108]
113 D 10/13/2012 1 [112]
我一直在玩partition by User order by date
,但我需要在获胜时“重置”每个分区,而且我似乎无法用任何方法解决它。 Lead() 和 lag() 也无济于事,因为我需要 Lead(x),其中 x 是每个分区的可变数字。
【问题讨论】:
【参考方案1】:嗯。您可以使用获胜的反向总和来识别组。然后,只需进行聚合:
select t.user, max(t.date) as date,
max(case when win = 1 then gameid end) as gameid,
array_agg(gameid order by date asc) filter (where win = 0) as gameid_losses
from (select t.*,
sum(wins) over (partition by user order by date desc) as grp
from t
) t
group by user, grp;
【讨论】:
非常聪明。非常感谢。以上是关于查找导致事件的行并将它们视为一个序列的主要内容,如果未能解决你的问题,请参考以下文章