题目

不同时间点的登录状态记录state_log如下
在这里插入图片描述
使用sql将其转化为如下表的不同时间段的相同登录状态记录
在这里插入图片描述

思路分析

此类问题需要用到laglead函数取上下行对应数据然后前后结果比较标签(0或1),再对标签所在列做累计求和,最后开窗按照累计值分组时间最大最小值状态
在这里插入图片描述

代码实现

SELECT 
    min(stime) stime_start,
    max(stime) stime_end,
    max(state) state
from(
        select 
            stime,
            state,
            stage_flag,
            sum(stage_flag) over(rows between unbounded preceding and current row) as accumulate
        from(
                select 
                    stime,
                    state,
                    if(state = pre_state, 0, 1) as stage_flag
                from(
                        select 
                            stime,
                            state,
                            lag(state,1,1) over() pre_state
                        from state_log
                    ) t1
            ) t2
    ) t3
group by accumulate;

代码结果分析

step1:

t1表核心点在lag(state,1,1) over() pre_state ,含义是取state列的结果向上取1行,取不到时候设定默认值为1。
注:
lag(col,n,DEFAULT)用于统计窗口内往上第n行值
第一个参数列名
第二个参数为往上第n行(可选,默认为1)
第三参数默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)
结果
在这里插入图片描述
step2:
if(state = pre_state, 0, 1) as stage_flag
对比state与pre_state的结果,相同的赋值0
t2表结果
在这里插入图片描述

step3
sum(stage_flag) over(rows between unbounded preceding and current row) as accumulate
开窗求累积到当前行的结果
t3表结果
在这里插入图片描述

step4
按累计值分组,求最终结果
在这里插入图片描述

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注