You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中如何合并多代理重叠会话的时间间隔?

计算代理的多重叠会话时间间隔

现有PostgreSQL日志表结构及数据如下:

id  dt                  session_id  agent_id state
7   2024-01-25 22:26:57 4           3148    0
7   2024-01-25 22:24:57 4           3148    1
6   2024-01-25 22:23:57 2           3148    0
5   2024-01-25 15:53:30 1           3148    0
4   2024-01-25 15:53:30 3           3148    0
3   2024-01-25 13:53:02 3           3148    1
2   2024-01-25 12:43:10 2           3148    1
1   2024-01-25 12:30:02 1           3148    1

其中state=1表示会话开始,state=0表示会话结束。

原使用lag()函数的方法仅能处理单会话场景,无法应对重叠会话的情况:

select agent_id, status, dt, lag(dt) over (partition by (agent_id) order by dt) as pre_status_dt  from 
(
    select *, 
      lag(status) over (partition by (agent_id) order by dt) as pre_status 
    from (
        select cs.dt, cs.user_id as agent_id, cs.status
        from "channel_subscribe" cs 
        where cs.channel = 14
    ) as t1
    where t1.dt >= '2024-01-01'
) as t2
where t2.status != t2.pre_status
order by dt asc

要合并重叠会话,可通过计算累计活跃会话数的方式实现,具体SQL如下:

WITH event_sequence AS (
    SELECT 
        agent_id,
        dt,
        state,
        -- 计算累计活跃会话数:开始+1,结束-1
        SUM(CASE WHEN state = 1 THEN 1 ELSE -1 END) 
            OVER (PARTITION BY agent_id ORDER BY dt) AS active_sessions,
        -- 获取上一条记录的活跃会话数,用于判断状态变化
        LAG(SUM(CASE WHEN state = 1 THEN 1 ELSE -1 END) 
            OVER (PARTITION BY agent_id ORDER BY dt)) 
            OVER (PARTITION BY agent_id ORDER BY dt) AS prev_active_sessions
    FROM channel_subscribe -- 替换为实际表名
    ORDER BY agent_id, dt
),
session_boundaries AS (
    SELECT 
        agent_id,
        dt,
        -- 标记时间段开始:从无活跃会话变为有活跃会话
        CASE WHEN prev_active_sessions = 0 AND active_sessions > 0 THEN 'start' END AS boundary_type
    FROM event_sequence
    UNION ALL
    SELECT 
        agent_id,
        dt,
        -- 标记时间段结束:从有活跃会话变为无活跃会话
        CASE WHEN prev_active_sessions > 0 AND active_sessions = 0 THEN 'end' END AS boundary_type
    FROM event_sequence
)
SELECT 
    agent_id,
    MAX(CASE WHEN boundary_type = 'start' THEN dt END) AS start_dt,
    MAX(CASE WHEN boundary_type = 'end' THEN dt END) AS end_dt
FROM (
    SELECT 
        agent_id,
        dt,
        boundary_type,
        -- 为每个连续的会话块分组
        COUNT(CASE WHEN boundary_type = 'start' THEN 1 END) 
            OVER (PARTITION BY agent_id ORDER BY dt) AS session_group
    FROM session_boundaries
    WHERE boundary_type IS NOT NULL
) AS grouped_boundaries
GROUP BY agent_id, session_group
ORDER BY agent_id, start_dt;

执行上述SQL后,将得到合并重叠会话后的结果:

agent_id  start_dt             end_dt
3148      2024-01-25 12:30:02  2024-01-25 22:23:57
3148      2024-01-25 22:24:57  2024-01-25 22:26:57

内容的提问来源于stack exchange,提问作者Alexey Panevin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:37:29