在Postgresql中计算每日中断
例如,我有停机开始日期时间:“2017-09-09 06:56:22”和结束日期时间:“2017-09-13 14:22:45”。 现在我想得到每天的停机持续时间,如果整个停机,那么给我“24:00:00”,但是如果一天中只有一部分停机,那么我们做减法,例如:startTime-DayEndTime(startTime),即开始一天结束时的00:00:00。 因此,如果一整天都有停电,那么每天都要计算24:00:00 如何在postgresql中解决此问题?请帮忙 见下表在Postgresql中计算每日中断,sql,postgresql,postgresql-9.3,Sql,Postgresql,Postgresql 9.3,例如,我有停机开始日期时间:“2017-09-09 06:56:22”和结束日期时间:“2017-09-13 14:22:45”。 现在我想得到每天的停机持续时间,如果整个停机,那么给我“24:00:00”,但是如果一天中只有一部分停机,那么我们做减法,例如:startTime-DayEndTime(startTime),即开始一天结束时的00:00:00。 因此,如果一整天都有停电,那么每天都要计算24:00:00 如何在postgresql中解决此问题?请帮忙 见下表 StartTime
StartTime EndTime OutageTime
2017-09-09 6:56:32 2017-09-10 0:00:00 17:03:28
2017-09-10 0:00:00 2017-09-11 0:00:00 24:00:00
2017-09-11 0:00:00 2017-09-12 0:00:00 24:00:00
2017-09-12 0:00:00 2017-09-13 0:00:00 24:00:00
2017-09-13 0:00:00 2017-09-13 14:22:45 14:22:45
只要是一整天,您就可以计算差异并将其替换为
24:00:00
:
SELECT starttime,
endtime,
CASE endtime - starttime
WHEN INTERVAL '1 day'
THEN '24:00:00'
WHEN INTERVAL '1 day 1 hour'
THEN '25:00:00'
ELSE CAST(endtime - starttime AS text)
END AS outagetime
FROM outages;
可以使用
generate_series()
执行此操作。以下是每天获得结果的逻辑:
select (case when date_trunc('day', g.dte) = date_trunc('day', o.start_time)
then g.dte
else date_trunc('day', g.dte)
end),
(case when date_trunc('day', g.dte) < date_trunc('day', o.end_time)
then date_trunc('day', g.dte) + interval '1 day'
else o.end_time
end)
from outages o, lateral
generate_series(start_time, end_time, interval '1 day') g(dte)
where g.dte < o.end_time;
select(日期('day',g.dte')=日期('day',o.start_时间)时的情况)
然后是g.dte
其他日期(日期,g.dte)
(完),,
(日期('day',g.dte)<日期('day',o.end_时间)时的情况)
然后日期(“天”,g.dte)+间隔“1天”
否则就要结束时间了
(完)
从停机到横向
生成序列(开始时间、结束时间、间隔“1天”)g(dte)
式中,g.dte
您可以使用子查询获取每天的跨度。请向我们展示一些表格样本数据以及您期望的输出。其两列“开始日期时间”和“结束日期时间”第三列是计算列。输出是这种格式的中断时间'hh:mm:ss'记住,如果有绝对中断,则为'24:00:00',因此只有相同的格式仅为时间请向我们显示一些表格样本数据以及您期望的输出。
从您的_表中选择starttime、endtime、endtime-starttime代码>也许>=间隔“1天”
会是一个更好的主意-刚刚好case@a_horse_with_no_name不确定,也许。。。但我忘了夏令时。不,不。如果停电超过一天,它应该在第二天的00:00:00截断。所以我们假设有不止一个答案,如果停机持续2天,我们有两个答案,如果3天,我们有3个答案answers@Emac4444我不明白。我所说的1天1小时
是指1天可以有超过24小时。尝试在时区“欧洲/维也纳”选择时间戳“2017-10-30 00:00:00”-在时区“欧洲/维也纳”选择时间戳“2017-10-29 00:00:00”
。
with t (startTime, endTime) as (values
('2017-09-09 6:56:32'::timestamptz,'2017-09-10 0:00:00'::timestamptz),
('2017-09-10 0:00:00','2017-09-11 0:00:00'),
('2017-09-11 0:00:00','2017-09-12 0:00:00'),
('2017-09-12 0:00:00','2017-09-13 0:00:00'),
('2017-09-13 0:00:00','2017-09-13 14:22:45'))
select startTime, endTime, upper(i) - lower(i) as a
from
(
select tstzrange(startTime, endTime) as tstzr, startTime, endTime
from t
) t
inner join (
select tstzrange(d, d + interval '1 day') as d
from
generate_series (
(select min(startTime)::date from t),
(select max(endTime) from t),
'1 day'
) gs (d)
) gs on d && tstzr
cross join lateral (
select tstzr * d as i
) cjl
;
starttime | endtime | a
------------------------+------------------------+----------
2017-09-09 06:56:32-03 | 2017-09-10 00:00:00-03 | 17:03:28
2017-09-10 00:00:00-03 | 2017-09-11 00:00:00-03 | 1 day
2017-09-11 00:00:00-03 | 2017-09-12 00:00:00-03 | 1 day
2017-09-12 00:00:00-03 | 2017-09-13 00:00:00-03 | 1 day
2017-09-13 00:00:00-03 | 2017-09-13 14:22:45-03 | 14:22:45