1.我们先使用如下代码表示出用户的出入

Select artical_id,in_time as dt,1 as rn from tb_user_log 
union all 
select artical_id,out_time as dt,-1 as rn from tb_user_log

输出的结果如下alt

我们用rn的1表示用户进入了观看,-1表示用户退出了观看。 例如第一行表示 9001在2021-11-01 10:00:00有一个用户开始观看。 我们将该表作为临时表,命名为t。

2.我们要求每篇文章同一时刻的最大观看人数,那就要先求出所有时刻的每篇文章的观看人数。这时我们考虑使用窗口函数。

select artical_id,sum(rn)over(partition by artical_id order by dt,rn desc) as uv
from t 
where artical_id!=0

需要注意的是题目中的两个关键点:

1.artical_id!=0才能保证是在看文章。

2.如果如果同一时刻有进入也有离开时,先记录用户数增加再记录减少,这里我们在窗口函数后使用rn desc 即可。如果是先减少再增加我们使用rn asc即可。

得出如下结果

alt

3.剩下的就比较简单了,从2中得出的表u再进行一个查询,group by artical_id,取出最大值,排序即可。

完整代码如下:

with t as 
(Select artical_id,in_time as dt,1 as rn from tb_user_log 
union all 
select artical_id,out_time as dt,-1 as rn from tb_user_log)

select artical_id,max(uv) as max_uv from 
(select artical_id,sum(rn)over(partition by artical_id order by dt,rn desc) as uv
from t 
where artical_id!=0) as u 
group by artical_id
order by max_uv desc