SQL189. 牛客直播各科目同时在线人数
描述
course_id | course_name | course_datetime |
1 | Python | 2021-12-1 19:00-21:00 |
2 | SQL | 2021-12-2 19:00-21:00 |
3 | R | 2021-12-3 19:00-21:00 |
user_id | course_id | in_datetime | out_datetime |
100 | 1 | 2021-12-01 19:00:00 | 2021-12-01 19:28:00 |
100 | 1 | 2021-12-01 19:30:00 | 2021-12-01 19:53:00 |
101 | 1 | 2021-12-01 19:00:00 | 2021-12-01 20:55:00 |
102 | 1 | 2021-12-01 19:00:00 | 2021-12-01 19:05:00 |
104 | 1 | 2021-12-01 19:00:00 | 2021-12-01 20:59:00 |
101 | 2 | 2021-12-02 19:05:00 | 2021-12-02 20:58:00 |
102 | 2 | 2021-12-02 18:55:00 | 2021-12-02 21:00:00 |
104 | 2 | 2021-12-02 18:57:00 | 2021-12-02 20:56:00 |
107 | 2 | 2021-12-02 19:10:00 | 2021-12-02 19:18:00 |
100 | 3 | 2021-12-03 19:01:00 | 2021-12-03 21:00:00 |
102 | 3 | 2021-12-03 18:58:00 | 2021-12-03 19:05:00 |
108 | 3 | 2021-12-03 19:01:00 | 2021-12-03 19:56:00 |
course_id | course_name | max_num |
1 | Python | 4 |
2 | SQL | 4 |
3 | R | 3 |
示例1
输入:
drop table if exists course_tb; CREATE TABLE course_tb( course_id int(10) NOT NULL, course_name char(10) NOT NULL, course_datetime char(30) NOT NULL); INSERT INTO course_tb VALUES(1, 'Python', '2021-12-1 19:00-21:00'); INSERT INTO course_tb VALUES(2, 'SQL', '2021-12-2 19:00-21:00'); INSERT INTO course_tb VALUES(3, 'R', '2021-12-3 19:00-21:00'); drop table if exists attend_tb; CREATE TABLE attend_tb( user_id int(10) NOT NULL, course_id int(10) NOT NULL, in_datetime datetime NOT NULL, out_datetime datetime NOT NULL ); INSERT INTO attend_tb VALUES(100, 1, '2021-12-1 19:00:00', '2021-12-1 19:28:00'); INSERT INTO attend_tb VALUES(100, 1, '2021-12-1 19:30:00', '2021-12-1 19:53:00'); INSERT INTO attend_tb VALUES(101, 1, '2021-12-1 19:00:00', '2021-12-1 20:55:00'); INSERT INTO attend_tb VALUES(102, 1, '2021-12-1 19:00:00', '2021-12-1 19:05:00'); INSERT INTO attend_tb VALUES(104, 1, '2021-12-1 19:00:00', '2021-12-1 20:59:00'); INSERT INTO attend_tb VALUES(101, 2, '2021-12-2 19:05:00', '2021-12-2 20:58:00'); INSERT INTO attend_tb VALUES(102, 2, '2021-12-2 18:55:00', '2021-12-2 21:00:00'); INSERT INTO attend_tb VALUES(104, 2, '2021-12-2 18:57:00', '2021-12-2 20:56:00'); INSERT INTO attend_tb VALUES(107, 2, '2021-12-2 19:10:00', '2021-12-2 19:18:00'); INSERT INTO attend_tb VALUES(100, 3, '2021-12-3 19:01:00', '2021-12-3 21:00:00'); INSERT INTO attend_tb VALUES(102, 3, '2021-12-3 18:58:00', '2021-12-3 19:05:00'); INSERT INTO attend_tb VALUES(108, 3, '2021-12-3 19:01:00', '2021-12-3 19:56:00');
输出:
1|Python|4 2|SQL|4 3|R|3
Mysql 解法, 执行用时: 36ms, 内存消耗: 6384KB, 提交时间: 2022-01-01
select ct.course_id,ct.course_name,bt.max_num from course_tb ct join( select course_id,max(at_num) as max_num from( select*, sum(num)over(partition by course_id order by course_id,at_time) as at_num from( select user_id,course_id,time(in_datetime) as at_time, 1 num from attend_tb union all select user_id,course_id,time(out_datetime) as at_time, -1 num from attend_tb order by course_id,at_time ) a ) b group by course_id ) bt on ct.course_id=bt.course_id
Mysql 解法, 执行用时: 36ms, 内存消耗: 6476KB, 提交时间: 2022-01-22
select e.course_id, e.course_name, max(cnt) max_num from (SELECT d.course_id, d.course_name, sum(zaixian) over (partition by course_id order by dt,zaixian desc) cnt from (select a.course_id, a.course_name, in_datetime dt, 1 zaixian from course_tb a left join attend_tb b on a.course_id=b.course_id union all select a.course_id, a.course_name , out_datetime dt, -1 zaixian from course_tb a left join attend_tb b on a.course_id=b.course_id ) d) e group by 1,2 order by 1
Mysql 解法, 执行用时: 37ms, 内存消耗: 6380KB, 提交时间: 2022-01-24
with t1 as ( select user_id, course_id, in_datetime as on_time, 1 as diff -- 进入直播间 from attend_tb union select user_id, course_id, out_datetime as on_time, -1 as diff -- 离开直播间 from attend_tb ), t2 as ( select course_id, sum(diff) over (partition by course_id order by on_time, diff desc) as num from t1 ), t3 as ( select distinct course_id, num, max(num) over (partition by course_id) as max_num from t2 ) select t3.course_id, c.course_name, t3.max_num from t3 left join course_tb c on c.course_id = t3.course_id where num = max_num order by course_id asc;
Mysql 解法, 执行用时: 37ms, 内存消耗: 6384KB, 提交时间: 2022-01-25
select course_id, course_name, max(ranks) as max_num from ( select a.course_id, course_name, sum(flag) over(partition by a.course_id, course_name order by times, flag desc) as ranks from ( select course_id, in_datetime as times, 1 as flag from attend_tb union all select course_id, out_datetime as times, -1 as flag from attend_tb ) as a left join course_tb as b on a.course_id = b.course_id ) as c group by course_id, course_name
Mysql 解法, 执行用时: 37ms, 内存消耗: 6416KB, 提交时间: 2021-12-19
-- 2021年12月18日 with attend_detail as ( select course_id, active_time, sum(cnt) as cnt from ( select course_id, in_datetime as active_time, 1 as cnt from attend_tb union all select course_id, out_datetime as active_time, -1 as cnt from attend_tb ) t group by course_id, active_time ) select t2.course_id as course_id , c.course_name as course_name , t2.max_num as max_num from ( select course_id, max(online_num) as max_num from ( select a1.course_id as course_id , a1.active_time as active_time , ifnull(sum(a2.cnt),0) as online_num from attend_detail a1 left outer join attend_detail a2 on a1.course_id = a2.course_id and a1.active_time >= a2.active_time -- where a1.cnt = 1 -- 最大人数必然最早发生在进入的时间 group by a1.course_id, a1.active_time ) t1 group by course_id ) t2 inner join course_tb c on t2.course_id = c.course_id order by course_id ;