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 应该不难,以使其完全准确。
基本上,我有一个像这样的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 应该不难,以使其完全准确。