一开始完全找不到算同一时刻最大在看人数的思路,看到别的大佬的答案才得到了启发。

思路:先算出每组artical_id的所有时刻的在看人数,再用group by语句找出每组artical_id最大的在看人数。那么怎么求每个时刻的在看人数呢?可以这么理解:in_time的时刻在看人数+1,out_time时刻在看人数-1,每一组artical_id内进行在看人数变化量按时间顺序的累加就可以算出每个时刻在看的人数,最后找出每组artical_id内最大的在看人数就是题目要求的同一时刻最大在看人数了。

理清思路后再来想SQL语句:

第一个难点在于UNION ALL的使用,这里是我没有想到的。in_time和out_time两种类别的人数变化可以直接用UNION ALL来处理。时刻dt有两种:in_time和out_time,人数变化量是diff有两种:+1和-1,union all连接后可以直接进行累加算出某时刻在看人数。

累积值的计算往往采用窗口函数,那么用sum(diff)over(partition by artical_id,order by dt),这里有个小细节,题目要求同一时刻先算增加的再算减少的,所以order by后还要加个diff desc字段。

最后求最大值是按artical_id分组。

最终代码为:

SELECT artical_id,max(instant_view) max_uv
FROM(SELECT artical_id,sum(diff)over(partition by artical_id order by dt,diff DESC) instant_view
    FROM(SELECT artical_id,in_time dt,1 diff
        FROM tb_user_log 
        WHERE artical_id!=0
        UNION ALL
        SELECT artical_id,out_time dt,-1 diff
        FROM tb_user_log
        WHERE artical_id!=0
        ) a
     )b 
GROUP BY artical_id
ORDER BY max_uv DESC;