使用Postgres获取每小时的总使用时间

时间:2018-02-21 11:40:03

标签: sql postgresql psql

输入:

-------------------------------------------
start_time           |  end_time           
-------------------------------------------
2019-03-28 04:00:00  |  2019-03-28 04:15:00
2019-03-28 04:00:00  |  2019-03-28 04:30:00
2019-03-28 04:40:00  |  2019-03-28 04:50:00
2019-03-28 04:50:00  |  2019-03-28 05:15:00
2019-03-28 05:15:00  |  2019-03-28 05:45:00
2019-03-28 06:15:00  |  2019-03-28 06:45:00
2019-03-28 07:00:00  |  2019-03-28 08:00:00
2019-03-29 04:00:00  |  2019-03-29 04:15:00
2019-03-29 04:00:00  |  2019-03-29 04:30:00
2019-03-29 04:40:00  |  2019-03-29 04:50:00
2019-03-29 04:50:00  |  2019-03-29 05:15:00
2019-03-29 05:15:00  |  2019-03-29 05:45:00
2019-03-29 06:15:00  |  2019-03-29 06:45:00
2019-03-29 07:00:00  |  2019-03-29 08:00:00

我想在不同的日期获得每小时的总利用时间。持续时间也可以在相同的持续时间内重叠。

期待输出:

------------------------------------------------------------
duration                                 |  utilised_time
------------------------------------------------------------
2019-03-28 12:00 - 2019-03-28 01:00      |    0
2019-03-28 01:00 - 2019-03-28 02:00      |    0
2019-03-28 02:00 - 2019-03-28 03:00      |    0
2019-03-28 03:00 - 2019-03-28 04:00      |    0
2019-03-28 04:00 - 2019-03-28 05:00      |    50
2019-03-28 05:00 - 2019-03-28 06:00      |    45
2019-03-28 06:00 - 2019-03-28 07:00      |    45
2019-03-28 07:00 - 2019-03-28 08:00      |    60
2019-03-28 08:00 - 2019-03-28 09:00      |    0
2019-03-29 12:00 - 2019-03-29 01:00      |    0
2019-03-29 01:00 - 2019-03-29 02:00      |    0
2019-03-29 02:00 - 2019-03-29 03:00      |    0
2019-03-29 03:00 - 2019-03-29 04:00      |    0
2019-03-29 04:00 - 2019-03-29 05:00      |    50
2019-03-29 05:00 - 2019-03-29 06:00      |    45
2019-03-29 06:00 - 2019-03-29 07:00      |    45
2019-03-29 07:00 - 2019-03-29 08:00      |    60
2019-03-29 08:00 - 2019-03-29 09:00      |    0

我们如何使用PSQL实现这一目标?

1 个答案:

答案 0 :(得分:2)

您可以使用generate_series()生成小时数。然后使用left joinaggregation

select g.ts, g.ts + interval '1 hour',
       sum(extract(epoch from (least(g.ts + interval '1 hour', i.end_time) -
                               greatest(g.ts, i.start_time)
                              )
                   )
          ) / 60 as duration_in_minutes
from generate_series('2019-03-28 12:00:00'::timestamp, '2019-03-29 08:00 - 2019-03-29 09:00:00'::timestamp, interval '1 hour'
                    ) g(ts) left join
       input i
       on i.start_time < g.ts + interval '1 hour' and
          i.end_time > g.ts
group by g.ts
order by g.ts;

您的结果和问题不清楚您想要的时间。你明确表示&#34;我希望在不同的日期获得每小时的总利用时间。&#34;但是,您的样本结果不是每小时都有。您可以使用where子句过滤所需的小时数。