将时间分配到间隔桶中

urb*_*ojo 5 sql postgresql date-arithmetic generate-series

我有下表:

CREATE TABLE f_contact (
    agent character varying,
    datetimeconnect timestamp without time zone,
    datetimedisconnect timestamp without time zone,
    duration integer
);
Run Code Online (Sandbox Code Playgroud)

duration是断开时间和连接时间之间的时间(以秒为单位)。
我可能有这样的数据:

agent   datetimeconnect         datetimedisconnect      duration
20024   2019-03-18 12:01:00.0   2019-03-18 13:01:30.0   3630
20011   2019-03-11 08:47:40.0   2019-03-11 09:30:10.0   2550
Run Code Online (Sandbox Code Playgroud)

我想获取这些数据并将时间分布在 15 分钟的间隔内,这样我得到的结果如下:

20024   12:00   840
20024   12:15   900
20024   12:30   900
20024   12:45   900 
20024   13:00   90
20011   08:45   740
20011   09:00   900
20011   09:15   900
20011   09:30   10
Run Code Online (Sandbox Code Playgroud)

如何实现这一目标?

Gor*_*off 3

这是一个有趣的问题。我稍微简化了列命名:

with t as (
      select 20024 as agent, '2019-03-18 12:01:00.0'::timestamp as conn, '2019-03-18 13:01:30.0'::timestamp as disconn, 3630 duration union all
      select 20011, '2019-03-11 08:47:40.0', '2019-03-11 09:30:10.0', 2550
     )
select gs.t, t.*,
       extract(epoch from least(gs.t + interval '15 minute', disconn) - greatest(gs.t, conn))
from t cross join lateral
     generate_series(date_trunc('hour', t.conn), date_trunc('hour', t.disconn) + interval '1 hour', interval '15 minute') gs(t)
where conn <= gs.t + interval '15 minute' and disconn >= gs.t ;
Run Code Online (Sandbox Code Playgroud)

是一个 db<>fiddle。

我意识到持续时间列是不必要的。您正在尝试捕获以 15 分钟为间隔的重叠秒数。

这会在小时边界上创建间隔——这更容易。这意味着某些重叠不正确,这就是该where子句过滤掉的内容。