题解 | #牛客直播各科目同时在线人数#
牛客直播各科目同时在线人数
http://www.nowcoder.com/practice/d69677e41f9a4bf3b3ed7a42573e9490
主要信息
- 课程表course_tb如下(其中course_id代表课程编号,course_name表示课程名称);行为表behavior_tb如下(其中user_id表示用户编号、if_sign表示是否报名、course_id代表课程编号);上课情况表attend_tb如下(其中user_id表示用户编号、course_id代表课程编号、in_datetime表示进入直播间的时间、out_datetime表示离开直播间的时间)
- 请你统计每个科目的出勤率(attend_rate(%),结果保留两位小数),出勤率=出勤(在线时长10分钟及以上)人数 / 报名人数,输出结果按course_id升序排序,以上数据的输出结果如下:
问题拆解
总体思路
- 标记法,将用户登陆状in_datetime和out_datetime进行标记
- 分组统计单个course_id课程的状态求和,即为在线状态
- 针对在线状态求最大值
具体实现
- 针对用户登陆状in_datetime标记为1和out_datetime标记为-1,登陆为1,登出为-1,用户是否在某个时间是否在线为用户状态相加
- 用户在线人数:course_id分组和时间in_datetime和out_datetime进行排序最后求和
- 用户最大在线人数:course_name需要course_id关联attend_tb和course_tb表,使用max对在线时间对应的在线人数求和
考点:同时在线人数的计算方式、UNION ALL、SUM窗口函数、max join group by等函数的灵活使用
SELECT course_id, course_name, max(num) AS max_num
FROM (
SELECT course_id, user_id, sum(tag) OVER (PARTITION BY course_id ORDER BY tms) AS num
FROM (
SELECT course_id, user_id, in_datetime AS tms, 1 AS tag
FROM attend_tb
UNION ALL
SELECT course_id, user_id, out_datetime AS tms, -1 AS tag
FROM attend_tb
) a1
) a
LEFT JOIN course_tb USING (course_id)
GROUP BY course_id
ORDER BY course_id;