又是一道瞬时最大UV的题目,这种题目有固定的做法,我整理了一下:

1、首先要理解,最大瞬时UV一定发生在某个用户进入直播间的瞬间

2、当用户进入直播间,记录进入时间,且UV+1;当用户退出直播间,记录退出时间,且UV-1;然后union all连接,目的是构建出这样一张表:每一个进出时间点的 用户进出明细记录 。

with a as (
        select 
        df1.course_id,
        df2.course_name,
        df1.in_datetime as "状态变动时间",
        1 as "uv"
        from attend_tb as df1
        left join course_tb as df2
        on df1.course_id = df2.course_id
        UNION ALL 
        select 
        df1.course_id,
        df2.course_name,
        df1.out_datetime as "状态变动时间",
        -1 as "uv"
        from attend_tb as df1
        left join course_tb as df2
        on df1.course_id = df2.course_id
)

3、第2步结束后,利用窗口,按课程id分组,按时间线升序,计算每个时间点的瞬时UV

SELECT 
course_id,
course_name,
sum(uv) OVER(PARTITION BY course_id ORDER BY 状态变动时间 asc rows between unbounded PRECEDING and current row) as "num"
from a

4、再套一层查询,取瞬时UV最大值

SELECT course_id,course_name,max(num) as "max_num"  from (
        SELECT 
        course_id,
        course_name,
        sum(uv) OVER(PARTITION BY course_id ORDER BY 状态变动时间 asc rows between unbounded PRECEDING and current row) as "num"
        from a
) as t
group by course_id,course_name
order by course_id asc

完整代码

with a as (
        select 
        df1.course_id,
        df2.course_name,
        df1.in_datetime as "状态变动时间",
        1 as "uv"
        from attend_tb as df1
        left join course_tb as df2
        on df1.course_id = df2.course_id
        UNION ALL 
        select 
        df1.course_id,
        df2.course_name,
        df1.out_datetime as "状态变动时间",
        -1 as "uv"
        from attend_tb as df1
        left join course_tb as df2
        on df1.course_id = df2.course_id
)

SELECT course_id,course_name,max(num) as "max_num"  from (
        SELECT 
        course_id,
        course_name,
        sum(uv) OVER(PARTITION BY course_id ORDER BY 状态变动时间 asc rows between unbounded PRECEDING and current row) as "num"
        from a
) as t
group by course_id,course_name
order by course_id asc