查找导致事件的行并将它们视为一个序列

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;

【讨论】:

非常聪明。非常感谢。

以上是关于查找导致事件的行并将它们视为一个序列的主要内容,如果未能解决你的问题,请参考以下文章

查找Google表格中的所有复选框

SSIS - 序列化/锁定包

识别非常接近的行组

Pandas - 查找和索引与行序列模式匹配的行

Java 忽略导入库中的默认接口方法并将它们视为抽象

选择字段中发生更改的行并将它们连接到另一个表