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

Sql 使用Postgres获取每小时的总利用时间,sql,postgresql,psql,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 | 20

输入:

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

预期输出:

------------------------------------------- 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
如何使用PSQL实现这一点?

您可以使用generate_系列生成小时数。然后使用左连接和聚合:


你的结果和你的问题不清楚你想要什么时间。您明确表示我希望在不同日期获得每小时的总利用时间。但是,您的示例结果并非每小时都有。您可以使用where子句筛选所需的小时数。

您可以使用generate_系列生成小时数。然后使用左连接和聚合:

你的结果和你的问题不清楚你想要什么时间。您明确表示我希望在不同日期获得每小时的总利用时间。但是,您的示例结果并非每小时都有。可以使用where子句筛选所需的小时数

------------------------------------------------------------ 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
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;