欢迎访问yhm138的博客园博客, 你可以通过 [RSS] 的方式持续关注博客更新

MyAvatar

yhm138

HelloWorld!

MySQL求最大同时在线人数的一种解法

题目地址

https://www.nowcoder.com/practice/d69677e41f9a4bf3b3ed7a42573e9490

思路

将所有区间的开始时刻和结束时刻作为tick。
之后按照区间开始等于这个tick还是区间结束等于这个tick,来决定是+1还是-1。
之后sum() over()做前缀和。
得到在这些tick附近的同时在线人数。
对每一门课程求最大同时在线人数。

代码

with total_info as(
    select ct.course_id,ct.course_name,
    at.in_datetime as interval_start,
    at.out_datetime as interval_end
    from course_tb ct
    left join attend_tb at
    using(course_id)
)
,
# 准备前缀和
t2 as(
    select *,
    (case when tick=interval_start then +1 when tick=interval_end then -1 else 0 end) as cnt_change,
    (case when interval_start=tick then 1 when interval_end=tick then 2 else 0 end) as sort_util_flag  # 如果某个时刻,有n人进入,有m人出去,同时在线人数的变动为:n个+1,之后m个-1
    # (case when interval_start=tick then 2 when interval_end=tick then 1 else 0 end) as sort_util_flag  # 如果某个时刻,有n人进入,有m人出去,同时在线人数的变动为:m个-1,之后n个+1
    from
    (
        select interval_start as tick from total_info
        union 
        select interval_end as tick from total_info
    )tmp1 
    left join total_info
    on interval_start=tick or interval_end=tick
) 

select course_id,course_name,max(online_uv) as max_num from 
(
    select course_id,course_name,
    sum(cnt_change) over(partition by course_id order by tick,sort_util_flag) as online_uv
    from t2
) t3
group by course_id,course_name
order by course_id asc
posted @   yhm138  阅读(130)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示