sql重复时长问题,如何去重详细讲解

重复时长问题描述:
访问某个会话未结束时,又开始另一个会话,会话时长会出现覆盖住,交叉,相互独立的情况,我们想统计去重后的时长,以下方案可以实现
样例数据

根据测试数据看出,有严重的时长重复,实际想统计的时长是60+30+110=200

实现代码如下

select
    id
	--4. 将每个时间段去重后的时长相加,得到总时长
  , sum(stage_duration)
from
    (
        select
            id
		  --3. 每个组取最大的end_time-最小的start_time即为这个连续时间段的去重时长
          , max(end_time) - min(start_time) stage_duration
        from
            (
                select
                    id
                  , start_time
                  , end_time
				  --2. 将打好标记的每个连续时间段分组,利用sum() over()开窗区分开每个连续时间段,
                  , sum(stage_flag) over(partition by id order by
                                         start_time) stage_flag
                from
                    (
                        select
                            id
                          , start_time
                          , end_time
						  --1. 将时间断开的打标记,即当前条的开始时间大于上一条的结束时间,认定为时长不连续,出现空隙,打标记
                          , if ( start_time > max(end_time) over( partition by id order by
                                                                 start_time,end_time ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) ,1,0 ) stage_flag
                        from
                            ( table ) t1
                    )
                    it1
            )
            tb1
        group by
            id
          , stage_flag
    )
    ot1
group by
    id
;

整体思路:

  1. 将时间断开的打标记,即当前条的开始时间大于上一条的结束时间,认定为时长不连续,出现空隙,打标记
  2. 将打好标记的每个连续时间段分组,利用sum() over()开窗区分开每个连续时间段,
  3. 每个组取最大的end_time-最小的start_time即为这个连续时间段的去重时长
  4. 将每个时间段去重后的时长相加,得到总时长

详细过程图示
详细过程图示

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值