sql - 在 PostgreSQL 中每小时累积经过的分钟数
问题描述
我有一个日期时间列。我需要导出从每小时的第一个到最后一个值按小时分组的总分钟数列,但是,在重叠事件的情况下,时间应该分布在两个小时之间。还有一种情况,如果两个连续记录之间经过的时间超过 30 分钟,则必须忽略它。
下面,我分三个阶段进行了说明,Original、Intermediate(计算运行总数)和 Final。
而且,我计划每小时采集一次增量数据,所以,我们如何正确地将它与旧数据合并是另一个问题。
样本数据:
Moves_TS
1/4/2020 10:00
1/4/2020 10:25
1/4/2020 10:42
1/4/2020 10:56
1/4/2020 10:59
1/4/2020 11:02
1/4/2020 11:24
1/4/2020 11:43
1/4/2020 11:55
1/4/2020 12:26
1/4/2020 12:29
中间层:
Moves_TS Hour Running Total
1/4/2020 10:00 10 0
1/4/2020 10:25 10 25
1/4/2020 10:42 10 42
1/4/2020 10:56 10 56
1/4/2020 10:59 10 60
1/4/2020 11:02 11 2
1/4/2020 11:24 11 24
1/4/2020 11:43 11 43
1/4/2020 11:55 11 55
1/4/2020 12:26 12 0
1/4/2020 12:29 12 3
最终输出:
Hour Work done/Hour
10 60
11 55
12 3
解决方案
这是一个带有一些曲折的缝隙和岛屿问题。首先,我将通过 30 分钟的间隔定义的“岛屿”进行总结:
select min(moves_ts) as start_ts, max(moves_ts) as end_ts
from (select o.*,
count(prev_moves_ts) filter (where moves_ts > prev_moves_ts + interval '30 minute') over (order by moves_ts) as grp
from (select o.*, lag(moves_ts) over (order by moves_ts) as prev_moves_ts
from original o
) o
) o
group by grp;
然后您可以使用它generate_series()
来扩展数据并计算每小时的重叠:
with islands as (
select min(moves_ts) as start_ts, max(moves_ts) as end_ts
from (select o.*,
count(prev_moves_ts) filter (where moves_ts > prev_moves_ts + interval '30 minute') over (order by moves_ts) as grp
from (select o.*, lag(moves_ts) over (order by moves_ts) as prev_moves_ts
from original o
) o
) o
group by grp
)
select hh.hh,
sum( least(hh.hh + interval '1 hour', i.end_ts) -
greatest(hh.hh, i.start_ts)
) as duration
from (select generate_series(date_trunc('hour', min(moves_ts)),
date_trunc('hour', max(moves_ts)),
interval '1 hour'
) hh
from original o
) hh left join
islands i
on i.start_ts < hh.hh + interval '1 hour' and
i.end_ts >= hh.hh
group by hh.hh
order by hh.hh;
这是一个 db<>fiddle。
推荐阅读
- vue.js - 动作中的 Vuex 访问状态很奇怪
- python - 每次更新我的条目时如何调用函数
- javascript - 在 flatpickr 中允许日期小于 minDate
- reactjs - 从 mapstatetoprops 重构为 React 中的钩子
- capacitor - 在离子电容器 LocalNotification 中每天但在不同时间重复相同通知的最佳方式
- node.js - 构建 docker 映像时,npm install 在 skaffold 中失败
- javascript - Discord Bot 用于踢出代码中由 id 确定的特定用户
- amazon-dynamodb - DynamoDB Streams - 多个子分片
- css - Transform 使用 css 旋转图像并获取要跟随的文本
- qt - 为什么 Qt Designer 中的布局拉伸因子限制为一定大小?