2017-09-20 28 views
0

我有例如中斷Start DateTime:'2017-09-09 06:56:22'和End DateTime:'2017-09-13 14:22:45'。 現在我想要獲得每日停電時間,如果整個停電時間都是'24:00:00',但是如果在一天的部分時間內有停電,那麼我們會執行減法,例如:startTime - DayEndTime(StartTime)即在該開始日的結尾00:00:00。 因此,如果每天都有停電,那麼每天都會計算24:00:00。在Postgresql中計算日常中斷

我如何在postgresql中解決這個問題?請幫助下

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 
+2

請向我們展示一些表格示例數據以及您期望的輸出。 –

+0

其第2列'開始日期時間'和'結束日期時間'是計算列。輸出是這種格式'hh:mm:ss'的中斷時間,請記住'24:00:00'的絕對中斷時間,因此只是相同的時間 – Emac4444

+0

請向我們展示一些表格示例數據以及輸出正在期待。 –

回答

0
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 
1

見表你可以只計算差值,並與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; 
+0

也許'> = interval'1 day''將是一個更好的主意 - 以防萬一 –

+1

@a_horse_with_no_name不知道,也許......但我忘了夏令時時間。 –

+0

否否。如果停電超過一天,則應在第二天的00:00:00截斷。所以我們假設有超過1個答案 – Emac4444

0

可以使用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; 

您可以使用子查詢來獲取每天的跨度。