SQL 查询持续时间作为连续时间戳差异,按天分组

SQL query duration as consecutive timestamps difference, grouped by day

基本上,我有一个像这样的table

id timestamp state minutes
1 7/12/2021, 17:38 off 14.54
1 7/12/2021, 17:53 running 8.39
1 7/12/2021, 18:01 off 8.12
1 9/12/2021, 00:04 running big value here

table按id排序,然后按timestamp升序排列。每个 id 代表一台机器,例如,在第一行中,机器 off 14.54 分钟,从 7/12/2021 17:38 到 7/12/2021 17:53(第二行)。在 17:53 时,机器启动 运行 8.39 分钟,直到 2021 年 7 月 12 日 18:01 等...

然后我所做的是将所有分钟相加并按日期和状态分组,这样我就知道每台机器关闭了多少时间 运行,每一天。问题是,当连续的时间戳来自不同的连续日期时,我得到了那一天的错误总和值。在上面 table 的示例中,我会得到 off 状态下的总分钟数总和为 14.54+ 8.39 + 8.12 + big value这里.

理想情况下应该是这样的组(只考虑关闭状态)

id day state minutes
1 7/12/2021 off 22.66
1 8/12/2021 off 1440
1 9/12/2021 off 4

我在想也许可以在结果 table 上人为地添加时间戳,例如“17/12/2021 24:00”,这样我在分组时每天都能正确地缩短间隔。

你能帮帮我吗?真的很重要!!谢谢

像这样:

with Cal as (
  select cast(DayStarts as date) as Date, DayStarts, DayStarts + interval '1 day' - interval '1 second' as DayEnds
  from (
        select  CAST('2021-12-07' AS timestamp(0)) + (n || ' day')::INTERVAL as DayStarts
        from generate_series(0, 10) n
       ) Cal1
),
MyTbl as (
  select 
      Tbl.id
    , tbl.timestamp as StartTS
    , tbl.state
    , timestamp + (tbl.minutes * interval '1 minute') as EndTS 
  from Tbl
)  
select 
    C.Date
  , T.State
  , sum(extract(Epoch from (least(C.DayEnds, T.EndTS)
                             -
                            greatest(C.DaySTarts, T.StartTS)+ interval '1 second'))/60) as minutes
from Cal C
    inner join
    MyTbl T
    on C.DayEnds>=T.StartTS
    and C.DaySTarts<=T.EndTS
group by C.Date, T.State
order by C.Date, T.State

Cal 是日历,为从 2021-12-07 开始的接下来的 10 天生成,它 returns 一个日期列,以及日期的 first/last 个时刻(时间戳)。 Tbl 是您的 table,MyTbl 是通过将分钟添加到时间戳列来加上结束时间戳 (EndTs)。 然后我们加入这些 table 寻找 'overlaps';然后对于每个重叠,我们计算重叠的分钟数,然后按日期和州聚合。

没有正确包含每天的最后一秒,但如果四舍五入到分钟就可以了。将其更改为使用 < NextDate 应该不难,以使其完全准确。