前言
同时在线相关的问题,在很多行业中也经常出现,比如:
- 统计同时最大主播数量
- 统计同时最大在线人数
- 统计同时最大打车人数
- …
很多人看到这类题,一脸懵逼,甚至连题意都看不懂,但是这道题是面试题中的常客,需要格外关注,尤其是互联网大厂喜欢考察,下面以统计某视频app同时在线最大主播数量为例
数据准备
1,2022-10-09 12:12:12,2022-10-09 18:12:12
2,2022-10-09 13:12:12,2022-10-09 16:12:12
3,2022-10-09 13:15:12,2022-10-09 20:12:12
4,2022-10-09 15:12:12,2022-10-09 16:12:12
5,2022-10-09 15:18:12,2022-10-09 20:12:12
1,2022-10-09 20:12:12,2022-10-09 23:12:12
6,2022-10-09 21:12:12,2022-10-09 23:15:12
7,2022-10-09 22:12:12,2022-10-09 23:10:12
共三列,第一列主播id、第二列上线时间、第三列下线时间
思路分析
同时在线的含义:同一时间点(一般精确到秒)在线。
最大人数:每秒都有新上线和下线的主播,需要求出最大的那一秒的人数
利用开窗函数累加
基本思想:上线一人加1,下线一人减1
代码思路:
- 将数据进行拆分,开播的记录标为 1,关播的记录记为-1,然后union在一起
- 将数据按照时间进行升序排序,然后对上下线标记的字段按时间顺序累加求和
- 累加的最大值就是同时在线的最多人数
代码如下:
select id, class, max(b.curr_online_cnt) from(
SELECT a.id,a.class,a.tt,a.flag,sum(a.flag) over (partition by class ORDER BY a.tt) AS curr_online_cnt FROM(
SELECT id,class,begintime AS tt,1 AS flag FROM view1
UNION ALL
SELECT id,class,endtime AS tt,-1 AS flag FROM view1
)a ORDER BY id
)b GROUP BY class;
SQL窗口函数OVER用法整理
OVER的定义
OVER用于为行定义一个窗口,它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。
语法
OVER ( [ PARTITION BY column ] [ ORDER BY culumn ] [ROWS|RANGE BETWEEN 边界规则1 and 边界规则2])
PARTITION BY 子句进行分组;
ORDER BY 子句进行排序;
ROWS|RANGE 框架是对窗口进行进一步的分区,框架有两种范围限定方式:一种是使用ROWS子句,通过指定当前行之前或之后的固定数目的行来限制分区中的行数;另一种是RANGE子句,按照排序列的当前值,根据相同值来确定分区中的行数。
窗口函数OVER()指定一组行,开窗函数计算从窗口函数输出的结果集中各行的值。
RANGE表示按照值的范围进行范围的定义,而ROWS表示按照行的范围进行范围的定义;边界规则的可取值见下表
用法
OVER开窗函数必须与聚合函数或排序函数一起使用,聚合函数一般指SUM(),MAX(),MIN,COUNT(),AVG()等常见函数。排序函数一般指RANK(),ROW_NUMBER(),DENSE_RANK(),NTILE()等。