sql - Postgresql tstzrange 交集总和
问题描述
我正在努力解决以下问题。我的 PostgreSQL 13 DB 中有以下表格。
( For the sake of this question I listed only relevant columns, and I replaced timestamps with integers!
)
包含来自计算机的记录(可能有 6 条)(其中 500 条)的表格,格式如下:
cmp_id | 状态 | 时间跨度(tstzrange) |
---|---|---|
cmp_1 | 一个 | 1 - 5 |
cmp_1 | 乙 | 5 - 7 |
cmp_1 | C | 7 - 14 |
cmp_1 | 乙 | 14 - 20 |
cmp_2 | 一个 | 2 - 8 |
cmp_2 | C | 8 - 9 |
cmp_2 | 乙 | 9 - 11 |
列出了这些计算机的维护表(只有 2 种类型):
cmp_id | type_of_mnt | 时间跨度(tstzrange) |
---|---|---|
cmp_1 | M1 | 2 - 6 |
cmp_1 | M1 | 8 - 9 |
cmp_2 | M1 | 3 - 4 |
cmp_2 | M1 | 5 - 6 |
cmp_2 | M2 | 9 - 10 |
在维护时间内报告的状态无关紧要,但要计算维护。
因此,如果用户选择从 1 到 21 的时间范围,我的目标是获得以下聚合视图。数字代表状态的持续时间。
cmp_id | 一个 | 乙 | C | M1 | M2 | 离线 |
---|---|---|---|---|---|---|
cmp_1 | 1 | 7 | 5 | 5 | 0 | 1 |
cmp_2 | 4 | 1 | 1 | 2 | 1 | 10 |
对于所选的不同时间窗口,数字也必须正确。即使它们在维护或状态期间开始或结束。
它基本上是将交叉口外的持续时间与维护时间相加并添加维护持续时间。所有这些都是通过在 state 列上旋转来完成的。离线列是日志之间的差距的总和。在上面的示例中,没有任何方法可以使其更简单。或者如果用户选择超过了可用数据的剩余时间。
我一直在尝试关注这篇文章,但没有取得多大成功。我已经能够对交叉点进行一些计算,例如计算重叠状态的真实持续时间:
with ranges as (
select
l.state,
upper(l.timespan) - lower(l.timespan) log_len,
upper(m.timespan) - lower(m.timespan) mnt_len,
upper(l.timespan * m.timespan) - lower(l.timespan * m.timespan) inters_len
from logs l
join maintenances m
on l.timespan && m.timespan
and l.cmp_id= m.cmp_id
)
select state, log_len, mnt_len, inters_len, log_len - inters_len as total
from ranges;
这给了我相交日志和维护的长度,以及日志的正确长度。但我还需要添加不相交日志的长度并进行旋转......
为了让事情变得更复杂(如果我们能解决这个问题),有人要求在“工作时间”或外面显示这个。因此,这一切都将在 6-18 小时内显示,并且仅在工作日显示......还有一个假期日期表也被排除在外。
解决方案
推荐阅读
- angular - Angular监听返回一些变量的函数
- android-studio - Android Studio Jetpack 撰写自动导入不再起作用
- reactjs - 从 react-hook-form 中的 react-select 组件获取值?
- python - 如何在我的类模型中将我的函数作为字段传递?
- ios - 如何使用 SwiftUI 创建带有刻度线的滑块?
- reactjs - React/Typescript - 对语法感到困惑
- python - 将 pyspark 数据帧转换为字典:结果与预期不同
- c# - 选定的行颜色和选定的单元格颜色
- sql-server - 登录用户的行级过滤是反模式吗?
- multiprocessing - python ssh netmiko pathos 客户端服务器,处理来自服务器与客户端 GIS 的文件路径