【场景】:某时刻同时在线人数

【分类】:窗口函数和分组函数的区别

分析思路

难点:

1.题目中说统计直播开始时的在线人数,使用小于等于。

注意窗口函数和分组函数的区别!见题解

(1)统计进入为增加人数,出去为减少人数

用tag来标记,进去增加人数1人,出去减少人数1人;然后把表连接起来

  • [使用]:union

(2)统计直播开始时(19:00),各科目的在线人数

统计直播开始时,所以要用小于等于

  • [条件]:datetime <= '19:00'

  • [使用]:窗口函数sum()

最终结果

select 查询结果 [课程号;课程名称;在线人数]
from 从哪张表中查询数据[多表]
where 查询条件 [时间小于等于19点]
order by 对查询结果排序 [课程号];

扩展

前往查看: MySQL 在线人数 场景分析

求解代码

方法一:

with子句 + 分组函数

with
    main as(
        #进入为增加人数,出去为减少人数
        select
            user_id,
            course_id,
            date_format(in_datetime,'%H:%i') as datetime,
            1 as tag
        from attend_tb
        union
        select
            user_id,
            course_id,
            date_format(out_datetime,'%H:%i') as datetime,
            -1 as tag
        from attend_tb
    )
#统计直播开始时(19:00),各科目的在线人数
select
    course_id,
    course_name,
    sum(tag) as online_num
from course_tb
left join main using(course_id)
where datetime <= '19:00'
group by course_id,course_name
order by course_id

方法二:

with子句 + 窗口函数

注意:因为有where条件不大于19:00的限制,所以窗口函数里面不需要再用order by tag desc;使用窗口函数必须去重,但是使用分组函数是course_id是唯一的,不需要去重。

with
    main as(
        #进入为增加人数,出去为减少人数
        select
            user_id,
            course_id,
            date_format(in_datetime,'%H:%i') as datetime,
            1 as tag
        from attend_tb
        union
        select
            user_id,
            course_id,
            date_format(out_datetime,'%H:%i') as datetime,
            -1 as tag
        from attend_tb
    )
#统计直播开始时(19:00),各科目的在线人数
select distinct
    course_id,
    course_name,
    sum(tag) over(partition by course_id) as online_num
from course_tb
left join main using(course_id)
where datetime <= '19:00'
order by course_id

方法三:

表连接

#统计直播开始时(19:00),各科目的在线人数
select
    course_id,
    course_name,
    sum(tag) as online_num
from course_tb
left join(
    #进入为增加人数,出去为减少人数
    select
        user_id,
        course_id,
        date_format(in_datetime,'%H:%i') as datetime,
        1 as tag
    from attend_tb
    union
    select
        user_id,
        course_id,
        date_format(out_datetime,'%H:%i') as datetime,
        -1 as tag
    from attend_tb
) main using(course_id)
where datetime <= '19:00'
group by course_id,course_name
order by course_id