当前位置: 首页 > news >正文

MySQL 在线人数 场景分析

一般在直播或者游戏中经常会统计用户在线人数,主要分为求每个时刻的在线人数和求某个时刻的在线人数两种。

【场景】:某个时刻的在线人数每个时刻的在线人数

【知识点】:窗口函数时间函数、sum(tag) over (order by dt,tag desc rows between unbounded preceding and current row)、窗口函数与分组函数的区别

一、分析思路

1、在线人数如何定义?

在线人数是指在某个时间段内,某一时刻在线的用户数。

可以求每个时刻的在线人数,也可以求某个时刻的在线人数。常用的是求每个时刻的同时在线人数,所以我们以其为例进行讲解

2、求解思路

要计算每个时刻的同时在线人数,我们可以按照以下步骤进行:

  1. 将所有登录和退出记录按照时间排序,得到一个按照时间递增的登录和退出记录。如果该记录表示用户登录,将其标记为1,如果表示用户退出标记为-1
  2. 利用窗口函数按照上述顺序对标记列进行累计求和:登录时人数+1,退出时人数-1。

3、MySQL执行步骤如下:

(1)获取标记好登录和退出的记录表

#将所有用户的进入和离开记录合并一起,统一为dt,并用tag为1和-1来标记进入还是离开
(selecta.登录日期 as dt,1 as tag
from 表名1 a)
union
(selecta.退出日期 as dt,-1 as tag
from 表名1 a)

这样就得到标记好登录和退出的记录

(2)对标记记录累计求和

#如果同一时刻有进入也有离开时,先记录用户数增加再记录减少,所以在窗口函数中使用sum()需要order by dt,tag desc
selectdt,sum(tag) over (order by dt,tag desc rows between unbounded preceding and current row) as 同时在线人数
from 标记好登录和退出的记录表

二、实例

下面就以两个实例讲清楚某个时刻的在线人数和每个时刻的在线人数。


两种问题的区别:

问题描述特点使用方法
每个时刻的用户在线人数求用户状态变动时刻的用户在线人数先获取标记好登录和退出的记录,然后按照时间和标记排序的顺序对标记列累计求和
某个时刻的用户在线人数限制条件(截止到某个时刻)的在线人数先获取标记好登录和退出的记录,然后对某个时刻前的标记列求和

(1)每个时刻的在线人数

案例来自:SQL163 每篇文章同一时刻最大在看人数
问题:统计每篇文章同一时刻最大在看人数,如果同一时刻有进入也有离开时,先记录用户数增加再记录减少,结果按最大人数降序。
示例:用户行为日志表tb_user_log(uid:用户ID, artical_id:文章ID, in_time:进入时间, out_time:离开时间, sign_in:是否签到)

iduidartical_idin_timeout_timesign_cin
110190012021-11-01 10:00:002021-11-01 10:00:110
210290012021-11-01 10:00:092021-11-01 10:00:380
310390012021-11-01 10:00:282021-11-01 10:00:580
410490022021-11-01 11:00:452021-11-01 11:01:110
510590012021-11-01 10:00:512021-11-01 10:00:590
610690022021-11-01 11:00:552021-11-01 11:01:240
710790012021-11-01 10:00:012021-11-01 10:01:500

根据示例,你的查询应返回以下结果:

artical_idmax_uv
90013
90022

解释:10点0分10秒时,有3个用户正在浏览文章9001;11点01分0秒时,有2个用户正在浏览文章9002。

求解代码:

withmain as(#用tag标记增加还是减少(selectartical_id,uid,in_time as dt,1 as tagfrom tb_user_logwhere artical_id != 0)union(selectartical_id,uid,out_time as dt,-1 as tagfrom tb_user_logwhere artical_id != 0)),main1 as(#如果同一时刻有进入也有离开时,先记录用户数增加再记录减少,所以在窗口函数中使用sum()需要order by dt,tag descselectartical_id,sum(tag) over (partition by artical_id order by dt,tag desc rows between unbounded preceding and current row) as uvfrom main)
#统计每篇文章同一时刻最大在看人数,结果按最大人数降序 
selectartical_id,max(uv) as max_uv
from main1
group by artical_id
order by max_uv desc
  • 标记好登录和退出的记录
	artical_id	uid		 					dt								tag
1		9001      101      2021-11-01 10:00:00      1	
2		9001      102      2021-11-01 10:00:09      1	
3		9001      103      2021-11-01 10:00:28      1		
4		9002      104      2021-11-01 11:00:45      1		
5		9001      105      2021-11-01 10:00:51      1		
6		9002      106      2021-11-01 11:00:55      1		
7		9001      107      2021-11-01 10:00:01      1		
8		9001      101      2021-11-01 10:00:11      -1		
9		9001      102      2021-11-01 10:00:38      -1		
10	9001      103      2021-11-01 10:00:58      -1		
11	9002      104      2021-11-01 11:01:11      -1		
12	9001      105      2021-11-01 10:00:59      -1		
13	9002      106      2021-11-01 11:01:24      -1		
14	9001      107      2021-11-01 10:01:50      -1
  • 对标记记录累计求和
		artical_id			 dt								tag
1		9001      2021-11-01 10:00:00      1	
2		9001      2021-11-01 10:00:01      2	
3		9001      2021-11-01 10:00:09      3		
4		9001      2021-11-01 10:00:11      2		
5		9001      2021-11-01 10:00:28      3		
6		9001      2021-11-01 10:00:38      2		
7		9001      2021-11-01 10:00:51      3		
8		9001      2021-11-01 10:00:58      2		
9		9001      2021-11-01 10:00:59      1		
10	9001      2021-11-01 10:01:50      0		
11	9002      2021-11-01 11:00:45      1		
12	9002      2021-11-01 11:00:55      2		
13	9002      2021-11-01 11:01:11      1		
14	9002      2021-11-01 11:01:24      0
  • 统计每篇文章同一时刻最大在看人数
artical_id	max_uv
1	9001				3
2	9002				2

(2)某个时刻的在线人数

案例来自:SQL186 牛客直播开始时各直播间在线人数
问题:请你统计直播开始时(19:00),各科目的在线人数,以上例子的输出结果为(按照course_name升序排序):

已知上课情况表attend_tb如下(其中user_id:用户编号、course_name:课程名称,course_datetime:上课时间、in_datetime:进入直播间的时间、out_datetime:离开直播间的时间):

user_idcourse_namecourse_datetimein_datetimeout_datetime
100Python2021-12-1 19:00-21:002021-12-01 19:00:002021-12-01 19:28:00
100Python2021-12-1 19:00-21:002021-12-01 19:30:002021-12-01 19:53:00
101Python2021-12-1 19:00-21:002021-12-01 19:00:002021-12-01 20:55:00
102Python2021-12-1 19:00-21:002021-12-01 19:00:002021-12-01 19:05:00
104Python2021-12-1 19:00-21:002021-12-01 19:00:002021-12-01 20:59:00
101SQL2021-12-2 19:00-21:002021-12-02 19:05:002021-12-02 20:58:00
102SQL2021-12-2 19:00-21:002021-12-02 18:55:002021-12-02 21:00:00
104SQL2021-12-2 19:00-21:002021-12-02 18:57:002021-12-02 20:56:00
107SQL2021-12-2 19:00-21:002021-12-02 19:10:002021-12-02 19:18:00
100R2021-12-3 19:00-21:002021-12-03 19:01:002021-12-03 21:00:00
102R2021-12-3 19:00-21:002021-12-03 18:58:002021-12-03 19:05:00
108R2021-12-3 19:00-21:002021-12-03 19:01:002021-12-03 19:56:00

示例数据的输出结果如下

course_nameonline_num
Python4
R1
SQL2

求解代码:

withmain as(#进入为增加人数,出去为减少人数selectuser_id,course_name,date_format(in_datetime,'%H:%i') as dt,1 as tagfrom attend_tbunionselectuser_id,course_name,date_format(out_datetime,'%H:%i') as dt,-1 as tagfrom attend_tb)
#统计直播开始时(19:00),各科目的在线人数
selectcourse_name,sum(tag) as online_num
from course_tb
left join main using(course_name)
where dt <= '19:00'
group by course_name
order by course_name;
  • 标记好登录和退出的记录
device_id 	course_name    dt					tag
100         Python        19:00        1          
100         Python        19:30        1          
101         Python        19:00        1          
102         Python        19:00        1          
104         Python        19:00        1          
101         SQL           19:05        1          
102         SQL           18:55        1          
104         SQL           18:57        1          
107         SQL           19:10        1          
100         R             19:01        1          
102         R             18:58        1          
108         R             19:01        1          
100         Python        19:28        -1         
100         Python        19:53        -1         
101         Python        20:55        -1         
102         Python        19:05        -1         
104         Python        20:59        -1         
101         SQL           20:58        -1         
102         SQL           21:00        -1         
104         SQL           20:56        -1         
107         SQL           19:18        -1         
100         R             21:00        -1         
102         R             19:05        -1         
108         R             19:56        -1         
  • 对截止时间点的标记记录求和
course_name    dt					online_num
Python        19:00        4                                              
R             18:58        1               
SQL           18:55        2             

扩展:

前往查看:MySQL 窗口函数与分组函数的区别

相关文章:

MySQL 在线人数 场景分析

一般在直播或者游戏中经常会统计用户在线人数&#xff0c;主要分为求每个时刻的在线人数和求某个时刻的在线人数两种。 【场景】&#xff1a;某个时刻的在线人数、每个时刻的在线人数 【知识点】&#xff1a;窗口函数、时间函数、sum(tag) over (order by dt,tag desc rows b…...

使用mybatis和dynamic-datasource-spring-boot-starter动态切换数据源操作数据库

记录&#xff1a;415 场景&#xff1a;使用mybatis和dynamic-datasource-spring-boot-starter动态切换数据源操作数据库。 版本&#xff1a;JDK 1.8,Spring Boot 2.6.3,dynamic-datasource-spring-boot-starter-3.3.2,mybatis-3.5.9。 源码&#xff1a;https://github.com/b…...

【日常刷题】迷宫问题

描述 定义一个二维数组 N*M &#xff0c;如 5 5 数组下所示&#xff1a; int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫&#xff0c;其中的1表示墙壁&#xff0c;0表示可以走的路&#xff0c;只能横着走…...

【Python童年游戏】满满的回忆杀—那些年玩过的童年游戏你还记得吗?那个才是你的菜?看到第一个我就泪奔了(致我们逝去的青春)

导语 滴一一学生卡&#x1f64c; 结伴上车的学生仔子们 用笑声打破车厢的沉默 大人眼里的晚高峰 是给放学后快乐&#x1f600;时光的加时 下车的学生匆匆起身带起 一阵熟悉的栀子香于&#x1f493; 是关于校园的记忆 开始零零散散地闪现 放学后集合的秘密基地/跟着城…...

C++ | 认识标准库string和vector

本文概要 本篇文章主要介绍C的标准库类型string和vector&#xff0c;文中描述和代码示例很详细&#xff0c;看完即可掌握&#xff0c;感兴趣的小伙伴快来一起学习吧。 &#x1f31f;&#x1f31f;&#x1f31f;个人简介 &#x1f31f;&#x1f31f;&#x1f31f; ☀️大家好&a…...

JAVA面试宝典: SpringCloud知识点(通俗易懂易背)

1、什么是 Spring Cloud&#xff1f; Spring Cloud 是基于 Spring Boot 的微服务架构开发工具箱&#xff0c;提供了在分布式系统中构建可靠的、弹性的、灵活的应用所需的大多数工具。Spring Cloud 中包含的子项目如下&#xff1a; Spring Cloud Config&#xff1a;配置管理工具…...

es学习笔记

集群环境下数据往哪个节点放? 路由计算&#xff1a;hash(id) %主分片的数量 集群环境下查数据怎么查&#xff1f; 分配控制&#xff1a;访问任何一个节点都能获取数据&#xff0c;随机访问到的这个节点称为协调节点&#xff08;访问了当前节点&#xff0c;不一定从当前节点…...

SAS学习第9章:卡方检验之适合性检验与独立性检验

卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度&#xff0c;实际观测值与理论推断值之间的偏离程度就决定卡方值的大小&#xff0c;如果卡方值越大&#xff0c;二者偏差程度越大&#xff1b;反之&#xff0c;二者偏差越小&#xff1b;若两个值完全相等时&#xf…...

马斯克爆料Twitter裁了八成员工;OpenAI CEO:GPT-5根本不存在;小鹏被曝年终奖打0.5折 | AI一周资讯

来源: AI前线 微信号&#xff1a;ai-front 整理 | 凌敏 微软宣布开源 Deep Speed Chat&#xff1b;消息称软银旗下 Arm 启动赴美 IPO&#xff1b;国家网信办出台生成式 AI 管理办法&#xff1b;前理想 AI 芯片一号位骄旸加入三星&#xff0c;负责组建 GPU 团队…… 资 讯 Op…...

ASEMI代理ADG1408YRUZ-REEL7原装ADI车规级ADG1408YRUZ-REEL7

编辑&#xff1a;ll ASEMI代理ADG1408YRUZ-REEL7原装ADI车规级ADG1408YRUZ-REEL7 型号&#xff1a;ADG1408YRUZ-REEL7 品牌&#xff1a;ADI /亚德诺 封装&#xff1a;TSSOP-16 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;16 类型&#…...

phpstudy本地环境搭建图文教程

作者&#xff1a;Eason_LYC 悲观者预言失败&#xff0c;十言九中。 乐观者创造奇迹&#xff0c;一次即可。 一个人的价值&#xff0c;在于他所拥有的。可以不学无术&#xff0c;但不能一无所有&#xff01; 技术领域&#xff1a;WEB安全、网络攻防 关注WEB安全、网络攻防。我的…...

【UE 控件蓝图】菜单及功能实现

素材资源连接&#xff1a;百度网盘 请输入提取码 密码&#xff1a;fvcw 效果 步骤 1. 创建蓝图&#xff0c;父类为“HUD” 命名为“MainMenuHUD”并打开 在事件图表中添加如下节点&#xff1a; 2. 创建控件蓝图&#xff0c;命名为“MainMenuWidget” 此时在“MainMenuHUD”的…...

Java 并发编程面试题——Future

目录 1.什么是 Future 模式&#xff1f;Java 中是如何实现的&#xff1f;2.Callable、Future 与 FutureTask 分别是什么&#xff1f;2.1.Callable 接口2.2.Future 接口2.3.FutureTask 类 3.CompletableFuture 类有什么用&#xff1f; 1.什么是 Future 模式&#xff1f;Java 中是…...

SpringBoot 介绍

1.简介 SpringBoot最开始基于Spring4.0设计&#xff0c;是由Pivotal公司提供的框架。 SpringBoot发展史&#xff1a; 2003年Rod Johnson成立Interface公司&#xff0c;产品是SpringFramework2004年&#xff0c;Spring框架开源&#xff0c;公司改名为Spring Source2008年&…...

自动驾驶作业手册

1 总 则 目的为保障港口内自动驾驶车辆安全使用,预防和减少事故,保护人民生命和财产安全,促进港口内业务开展。 含义和范围港口内自动驾驶车辆,是指电脑驾驶车辆,为一种运输动力的无人地面载具,与有人驾驶车辆不同,其具备不需要人类操作即可以感测其环境及导航功能,能…...

MySQL调优笔记——慢SQL优化记录(2)

今天调优的原因是&#xff0c;有一个统计报表业务&#xff0c;查询的时间太慢&#xff1b;同时由于数据库的压力是随机性的&#xff0c;这个业务的执行下限和上限相差近20倍&#xff1b;快的时候可以达到600ms&#xff0c;慢的时候有9秒之多&#xff1b; 接下来详细介绍&#x…...

二叉排序树的插入和删除操作(python实现)

二叉排序树的插入和删除操作都是在保持二叉排序树特性的前提下进行的。 插入操作&#xff1a; 在二叉排序树中插入一个新节点时&#xff0c;先比较新节点的值和当前节点的值的大小关系&#xff0c;若小于当前节点&#xff0c;则继续在当前节点的左子树中查找&#xff1b;若大…...

算法记录 | Day35 贪心算法

860.柠檬水找零 思路&#xff1a; 只需要维护三种金额的数量&#xff0c;5&#xff0c;10和20。 有如下三种情况&#xff1a; 情况一&#xff1a;账单是5&#xff0c;直接收下。情况二&#xff1a;账单是10&#xff0c;消耗一个5&#xff0c;增加一个10情况三&#xff1a;账…...

coinex // 撮合引擎 逻辑流程 (两种数据源 初始化源和前端源)

目录 1 生产者 数据源 1.1. match-server 一启动 初始化数据 自动查询数据库 查询level2要展示的数据 1.2 match-server接收 前端发给Exchange-server的数据 2. 将查询/接受的数据EntrustOrder 转成 Order 解耦 过滤掉不要的属性 3.Order转成 OrderEvent 4. 分配序号发布…...

CentOS7---部署LNMP数据存储到redis

一、部署LNMP及redis 1、部署LNMP&#xff0c;需要将 tengine-2.2.0.tar.gz 拷贝到虚拟机的 /root 目录下 步骤一&#xff1a;安装nginx 源码安装相关软件包 # pcre-devel做正则匹配&#xff0c;zlib-devel做数据压缩 [roottemplate ~]# yum -y install gcc pcre-devel zlib-de…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...