获取时间跨度内的会话持续时间平均值

Get session duration averages over time spans

table结构是这样的:

table name : log

session_id                              event_type      time
-------------------------------------------------------------------------------------
6983bb14-09e1-4697-ac6f-1528bb252a07    session_start   2019-09-12 13:40:18.307411+00
6983bb14-09e1-4697-ac6f-1528bb252a07    session_end     2019-09-12 13:41:42.000399+00
38866490-c1d6-4036-a7f9-c9cfa9bf23b4    session_start   2019-09-12 14:07:35.34742+00
38866490-c1d6-4036-a7f9-c9cfa9bf23b4    session_end     2019-09-12 14:09:01.873879+00
c00d41ae-6e1c-4b52-8bcc-009cfcc96c5a    session_start   2019-09-12 14:09:51.940051+00
c00d41ae-6e1c-4b52-8bcc-009cfcc96c5a    session_end     2019-09-12 14:11:02.085879+00
9c07101e-f09d-43ac-ba86-b92ea19e2d22    session_start   2019-09-12 14:15:43.66439+00
9c07101e-f09d-43ac-ba86-b92ea19e2d22    session_end     2019-09-12 14:18:17.38121+00
...

我正在尝试查询 table 以获得以下所需结果:

day           avg_session_duration(seconds)
--------------------------------------------
2019-09-12   1200
2019-09-13   800
...

您可以聚合两次:

select 
    session_time::date "day",
    avg(session_duration_seconds) avg_session_duration_seconds
from (
    select 
        session_id,
        min(time) session_time,
        extract(epoch from (max(time) - min(time))) session_duration_seconds
    from log
    group by session_id
) t
group by session_time::date
order by session_time::date

这在以下假设下有效:

  • 两个不同的会话永远不会共享相同的 session_id
  • 一个给定的会话在 table 中有两个且只有两个条目,第一个对应于会话的开始,第二个对应于它的结束
  • timetimestamp 数据类型(否则您需要先转换它)

left joingroup by将达到这个要求。

select t1.session_time
    , avg(t2.ss - t1.ss)  as avg_session_duration
from (
    select session_time::date as dt
        , sum(extract(epoch from session_time::time)) ss
    from 
    tableA 
    where event_type = 'session_start'
    group by session_time::date) as t1
left join(
    select session_time::date as dt
        , sum(extract(epoch from session_time::time)) ss
    from 
    tableA  
    where event_type = 'session_end'
    group by session_time::date) as t2 on t2.dt = t1.dt