从具有 start/stop 事件且重复 start/stop 记录的时间戳列查看会话

Review sessions from timestamp column with start/stop event with duplicate start/stop records

我有以下案例变更记录:

id case_id state time_created
1 100 REVIEW_NEEDED 2021-03-30 15:11:58.015907000
2 100 REVIEW_NEEDED 2021-04-01 13:08:17.945926000
3 100 REVIEW 2021-04-07 06:20:48.873865000
4 100 WAITING 2021-04-07 06:32:47.159664000
5 100 REVIEW_NEEDED 2021-04-09 06:32:51.132127000
6 100 REVIEW 2021-04-12 04:39:36.426467000
7 100 REVIEW 2021-04-12 04:40:36.000000000
8 100 CLOSED 2021-04-12 04:40:43.133736000
9 101 REVIEW_NEEDED 2021-03-30 20:37:58.015907000
10 101 REVIEW 2021-04-04 13:08:17.945926000
11 101 CLOSED 2021-04-06 06:20:48.873865000
12 101 CLOSED 2021-04-06 06:20:50.000000000

我想报告其中的会话,如下所示:

open_id close_id case_id waiting_time_start handling_time_start handling_time_end
1 4 100 2021-03-30 15:11:58.015907000 2021-04-07 06:20:48.873865000 2021-04-07 06:32:47.159664000
5 8 100 2021-04-09 06:32:51.132127000 2021-04-12 04:39:36.426467000 2021-04-12 04:40:43.133736000
9 11 101 2021-03-30 20:37:58.015907000 2021-04-04 13:08:17.945926000 2021-04-06 06:20:48.873865000

Waiting_time_start:当状态=REVIEW_NEEDED

Handling_time_start: 当状态=REVIEW

Handling_time_end:当state=WAITING或CLOSED时

我目前的解决方案是对Waiting_time_startHandling_time_start[进行排名=48=] 每个案例,然后将这些事件加入排名,但这并不完美,因为存在重复记录,因此 start/stop 个事件的数量可能因案例而异。

非常感谢任何想法!

这个比较复杂。首先根据“等待”和“关闭”的计数添加分组——但仅当它们更改值时:

select t.*,
       sum(case when (state <> next_state or next_state is null) and
                     state in ('WAITING', 'CLOSED')
                then 1 else 0
           end) over (partition by caseid order by time_created desc) as grouping
from (select t.*,
             lead(state) over (partition by caseid order by time_created) as next_state
      from t
     ) t

然后,您可以汇总:

with cte as (
      select t.*,
             sum(case when (state <> next_state or next_state is null) and
                           state in ('WAITING', 'CLOSED')
                      then 1 else 0
                 end) over (partition by caseid order by time_created desc) as grouping
      from (select t.*,
                   lead(state) over (partition by caseid order by time_created) as next_state
            from t
           ) t
     )
select caseid, min(id), max(id),
       min(case when status = 'REVIEW_NEEDED' then time_created end),
       min(case when status = 'REVIEW' then time_created end),
       max(time_created)
from cte
group by grouping, caseid;