比方说,我有一个包含服务中断列表的表。
这些字段是: service_id、from_time、to_time。时间是时间戳类型。
使用这些间隔的服务的状态是“下降”的。其他时候是“起床”。
我正在寻找一个查询,它将返回一个表示给定日期到现在之间的特定服务健康状态的时间间隔的连续列表。
例如,该表仅包含服务srv1的一次中断:
srv1, 11/01/2017 13:43:32, 11/01/2017 15:20:12, DOWN
那么,“乞讨年”的查询结果应该如下所示:
srv1, 11/01/2017 15:20:12, 24/07/2017 23:55:00, UP
srv1, 11/01/2017 13:43:31, 11/01/2017 15:20:12, DOWN
srv1, 01/01/2017 00:00:00, 11/01/2017 13:43:31, UP
假设中断不是重叠的。
以下间隔的from_time等于服务的上一个时间间隔的to_time。
如果服务当前处于关闭状态,那么to_time在中断表中等于NULL。
这个查询是针对PG 9.6的
发布于 2017-07-24 11:11:35
基本上,你想:
为此目的,以下代码使用union all
:
select t.*
from t
union all
select id, coalesce(prev_to_time, '2017-01-01'::timestamp) as start_time,
start_time as to_time,
(case when status = 'DOWN' then 'UP' else 'DOWN' end) as status
from (select t.*,
lag(to_time) over (partition by id order by start_time) as prev_to_time,
lag(status) over (partition by id order by start_time) as prev_status
from t
) t
where (prev_to_time is null and start_time <> '2017-01-01'::timestamp or
prev_to_time <> start_time
) and
(prev_status is distinct from status)
union all
select id, max(end_time), now(), 'UP'
from t
group by id
having max(end_time) <> now()
order by id, start_time;
发布于 2017-07-24 11:24:03
您可以使用延迟()函数来回顾前一行。
在这种情况下,类似于:
with down as (select *, lag(to_time) over (rows unbounded preceding)
as last_up
from outage order by from_time asc),
full_log as (select host, from_time, to_time, 'down'
AS as status
FROM down
UNION ALL
select host, last_up, from_time, 'up' as status
from down)
select * from full_log order by from_time asc;
https://stackoverflow.com/questions/45279045
复制相似问题