主播同时在线问题

如下为某直播平台主播开播及关播时间,根据该数据计算出平台最高峰同时在线的最多的主播人数。

思路:

1.将上线时间作为 +1,下线时间作为 -1

2.然后运用union all 合并两列

3.利用sum() over()对其分区排序,求出不同时间段的人数(每一个时间点都会对应一个总在线人数)

4.对时间进行分组,求出所有时间点中最大的同时在线总人数

id stt edt

1001 2021-06-14 12:12:12 2021-06-14 18:12:12

1003 2021-06-14 13:12:12 2021-06-14 16:12:12

1004 2021-06-14 13:15:12 2021-06-14 20:12:12

1002 2021-06-14 15:12:12 2021-06-14 16:12:12

1005 2021-06-14 15:18:12 2021-06-14 20:12:12

1001 2021-06-14 20:12:12 2021-06-14 23:12:12

1006 2021-06-14 21:12:12 2021-06-14 23:15:12

1007 2021-06-14 22:12:12 2021-06-14 23:10:12

mkdir data

create database datahive;

use datahive;

drop table if exists test;

create table test(

id string,

stt Timestamp ,

edt Timestamp

)row format delimited

fields terminated by ' '; --列的分割符

load data local inpath '/guojinkun' overwrite into table test;

分析

将一条数据拆分成两条(id,dt,p),并且对数据进行标记:开播为1,关播为-1,1表示有主播开播在线,-1表示有主播关播离线,其中dt为开播时间或者关播时间:

id dt p

1001 2021-06-14 12:12:12 1

1001 2021-06-14 18:12:12 -1

1001 2021-06-14 20:12:12 1

1001 2021-06-14 23:12:12 -1

1002 2021-06-14 15:12:12 1

1002 2021-06-14 16:12:12 -1

1003 2021-06-14 13:12:12 1

1003 2021-06-14 16:12:12 -1

1004 2021-06-14 13:15:12 1

1004 2021-06-14 20:12:12 -1

1005 2021-06-14 15:18:12 1

1005 2021-06-14 20:12:12 -1

1006 2021-06-14 21:12:12 1

1006 2021-06-14 23:15:12 -1

1007 2021-06-14 22:12:12 1

1007 2021-06-14 23:10:12 -1

然后按照dt排序,求某一时刻的主播在线人数,对时间排序,然后直接对那时刻之前的p求和即可。

那要求一天中最大的同时在线人数,就需要先分别求出每个时刻的同时在线人数,再取最大值即可。需要用到开窗函数:sum() over(…)

解法:

-- 1) 对数据分类,在开始数据后添加正1,表示有主播上线,同时在关播数据后添加-1,表示有主播下线

select id , stt as dt , 1 as p from test

union all

select id , edt as dt , -1 as p from test;

记为 t1

得到:

1001 2021-06-14 12:12:12 1

1001 2021-06-14 18:12:12 -1

1001 2021-06-14 20:12:12 1

1001 2021-06-14 23:12:12 -1

1002 2021-06-14 15:12:12 1

1002 2021-06-14 16:12:12 -1

1003 2021-06-14 13:12:12 1

1003 2021-06-14 16:12:12 -1

1004 2021-06-14 13:15:12 1

1004 2021-06-14 20:12:12 -1

1005 2021-06-14 15:18:12 1

1005 2021-06-14 20:12:12 -1

1006 2021-06-14 21:12:12 1

1006 2021-06-14 23:15:12 -1

1007 2021-06-14 22:12:12 1

1007 2021-06-14 23:10:12 -1

排序后:

1001 2021-06-14 12:12:12 1

1003 2021-06-14 13:12:12 1

1004 2021-06-14 13:15:12 1

1002 2021-06-14 15:12:12 1

1005 2021-06-14 15:18:12 1

1002 2021-06-14 16:12:12 -1

1003 2021-06-14 16:12:12 -1

1001 2021-06-14 18:12:12 -1

1001 2021-06-14 20:12:12 1

1004 2021-06-14 20:12:12 -1

1005 2021-06-14 20:12:12 -1

1006 2021-06-14 21:12:12 1

1007 2021-06-14 22:12:12 1

1007 2021-06-14 23:10:12 -1

1001 2021-06-14 23:12:12 -1

1006 2021-06-14 23:15:12 -1

-- 2) 按照时间排序,计算累加人数

select

t1.id,

t1.dt,

sum(p) over(partition by date_format(t1.dt, 'yyyy-MM-dd') order by t1.dt) sum_p

from (

select id , stt as dt , 1 as p from test

union all

select id , edt as dt , -1 as p from test

) t1

记为 t2

得到:

1001 2021-06-14 12:12:12 1

1003 2021-06-14 13:12:12 2

1004 2021-06-14 13:15:12 3

1002 2021-06-14 15:12:12 4

1005 2021-06-14 15:18:12 5

1002 2021-06-14 16:12:12 3

1003 2021-06-14 16:12:12 3

1001 2021-06-14 18:12:12 2

1001 2021-06-14 20:12:12 1

1004 2021-06-14 20:12:12 1

1005 2021-06-14 20:12:12 1

1006 2021-06-14 21:12:12 2

1007 2021-06-14 22:12:12 3

1007 2021-06-14 23:10:12 2

1001 2021-06-14 23:12:12 1

1006 2021-06-14 23:15:12 0

-- 3) 找出同时在线人数最大值

select

date_format(t2.dt,'yyyy-MM-dd') `date`,

max(sum_p) con

from(

select

t1.id,

t1.dt,

sum(p) over(partition by date_format(t1.dt, 'yyyy-MM-dd') order by t1.dt) sum_p

from (

select id , stt as dt , 1 as p from test

union all

select id , edt as dt , -1 as p from test

) t1

) t2

group by date_format(t2.dt,'yyyy-MM-dd');

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: