PostgreSQL集群不间断系列数据

问题描述 投票:0回答:1

这是输入和所需输出的示例,我认为这比我描述需求更容易理解。

  • 输入数据 (业务逻辑解释:所有时长>1M的都设置为0M)
名字 开始 结束 差异 正在进行的_序列
测试1 2024-04-21 00:00:21 2024-04-21 00:01:21 00:01:00 1
测试1 2024-04-21 00:01:21 2024-04-21 00:02:21 00:01:00 1
测试1 2024-04-21 00:02:21 2024-04-21 00:03:21 00:01:00 1
测试1 2024-04-21 00:03:21 2024-04-21 00:15:21 00:00:00 0
测试1 2024-04-21 00:15:21 2024-04-21 00:16:21 00:01:00 1
测试1 2024-04-21 00:16:21 2024-04-21 00:17:21 00:01:00 1
测试1 2024-04-21 00:17:21 2024-04-21 00:23:21 00:00:00 0
测试2 2024-04-22 00:00:21 2024-04-22 00:01:21 00:01:00 1
测试2 2024-04-22 00:01:21 2024-04-22 00:02:21 00:01:00 1
  • 预期结果;它应该导致每个不间断的ongoing_sequence产生一条记录以及差异之和。
名字 分钟开始时间 最大结束 差异
测试1 2024-04-21 00:00:21 2024-04-21 00:03:21 00:03:00
测试1 2024-04-21 00:15:21 2024-04-21 00:17:21 00:02:00
测试2 2024-04-22 00:00:21 2024-04-22 00:02:21 00:02:00

您能给我一些关于如何直接在 SQL 中以高性能方式实现它的建议吗?迭代结果并以这种方式创建输出不是一种选择。

提前致谢!

存在类似的帖子,例如按时间段分组,但这不会产生预期的结果。

sql postgresql window-functions gaps-and-islands
1个回答
0
投票

您可以使用滚动(步进翻滚

count()over window1
db<>fiddle 的演示:

select name
      ,min("start")    as max_start
      ,max("end")      as max_end
      ,sum(difference) as difference
from(select *,count(*)filter(where ongoing_sequence=0)over(w1) as seq_no
     from test
     window w1 as (partition by name order by "start"))_
where ongoing_sequence<>0
group by name,seq_no;
名字 最大开始时间 最大结束 差异
测试1 2024-04-21 00:00:21 2024-04-21 00:03:21 00:03:00
测试2 2024-04-22 00:00:21 2024-04-22 00:02:21 00:02:00
测试1 2024-04-21 00:15:21 2024-04-21 00:17:21 00:02:00

order by "start"
意味着
range between unbounded preceding and current row
,这意味着每一行都会回顾并计算到目前为止有多少个间隙。每个不间断的行序列将共享该计数 - 如果存在间隙,则会递增。
在外部查询中,您只需忽略间隙行并将共享序列号添加到
group by "name"

这称为“间隙与岛屿”问题。

© www.soinside.com 2019 - 2024. All rights reserved.