游戏行业实战案例 5 :玩家在线分布

3ab8bdd353f320281fccdb77aa6ecbd7.png

【面试题】某游戏数据后台设有“登录日志”和“登出日志”两张表。

「登录日志」记录各玩家的登录时间和登录时的角色等级。 

961ca44388a09104d4e4c16d53d057c3.png

「登出日志」记录各玩家的登出时间和登出时的角色等级。

23530e6d0100def937602f0563dbb065.png

其中,「角色 id 」字段唯一识别玩家。

游戏开服前两天( 2022-08-13 至 2022-08-14 )的角色登录和登出日志如下

7d5341af52fef043b644f57fe7bd309e.png

7848d2cdbdbd1ff156ce96177453162d.png

一天中,玩家可以多次登录登出游戏,请使用 SQL 分析出以下业务问题:

请根据玩家登录登出的时间,统计在开服首日各玩家在线时长分布。

(如玩家登录后没有对应的登出日志,可以使用当天 23:59:59 作为登出时间,时间之间的计算可以考虑使用时间戳函数 unix_timestamp 。【区分在线时间段:0-30min ,30min-1h ,1-2h ,2-3h ,3-5h ,5h 以上;区间为左闭右开】)

问题 5 :

统计在开服首日各玩家在线时长分布,其中区分在线时间段:0-30min ,30min-1h ,1-2h ,2-3h ,3-5h ,5h 以上,区间为左闭右开,解释为大白话即为:统计2022-08-13,在线时间段在 0-30min 、30min-1h 、1-2h 、 2-3h 、3-5h 、5h 以上的玩家各有多少人。

统计人数使用 count() 函数,而玩家的在线时间段可以用 case when 子句进行条件判断,即使用 case when 子句判断各玩家的总在线时长在哪个在线时间段内:

case when 总在线时长_min>=0 and 总在线时长_min<30 then '0-30min'
when 总在线时长_min>=30 and 总在线时长_min<60 then '30min-1h'
when 总在线时长_min>=60 and 总在线时长_min<120 then '1-2h'
when 总在线时长_min>=120 and 总在线时长_min<180 then '2-3h'
when 总在线时长_min>=180 and 总在线时长_min<300 then '3-5h'
else '5h以上' end

将问题 4 中统计各玩家每天的总在线时长的查询结果设为临时表 d ,则判断开服首日,各玩家的总在线时长在哪个在线时间段内的 SQL 的书写方法:

select 角色id,(case when 总在线时长_min>=0 and 总在线时长_min<30 then '0-30min'when 总在线时长_min>=30 and 总在线时长_min<60 then '30min-1h'when 总在线时长_min>=60 and 总在线时长_min<120 then '1-2h'when 总在线时长_min>=120 and 总在线时长_min<180 then '2-3h'when 总在线时长_min>=180 and 总在线时长_min<300 then '3-5h'else '5h以上' end) as 在线时间段
from d
where 日期 = '2022-08-13';

利用 with…as 语句来封装临时表 d 的查询语句,则 SQL 的书写方法:

with d as
(with c as
(select a.角色id,a.日期,a.登录时间,(case when b.登出时间 is null then concat(a.日期,'23:59:59') else b.登出时间 end) as 登出时间
from
(select 角色id,日期,登录时间,rank() over(partition by 角色id,日期 order by 登录时间 asc) as 登录排名
from 登录日志) as a
left join
(select 角色id,日期,登出时间,rank() over(partition by 角色id,日期 order by 登出时间 asc) as 登出排名
from 登出日志) as b
on a.角色id = b.角色id and a.日期 = b.日期 and a.登录排名 = b.登出排名
)
select 角色id,日期,
sum(round((unix_timestamp(登出时间)- unix_timestamp(登录时间))/60,2)) as 总在线时长_min
from c
group by 角色id,日期
)
select 角色id,(case when 总在线时长_min>=0 and 总在线时长_min<30 then '0-30min'when 总在线时长_min>=30 and 总在线时长_min<60 then '30min-1h'when 总在线时长_min>=60 and 总在线时长_min<120 then '1-2h'when 总在线时长_min>=120 and 总在线时长_min<180 then '2-3h'when 总在线时长_min>=180 and 总在线时长_min<300 then '3-5h'else '5h以上' end) as 在线时间段
from d
where 日期 = '2022-08-13';

查询结果如下:

04d26f64f88569420477112fb5856746.png

现在我们来计算各在线时间段的玩家人数,同样,使用 group by 子句和 count() 函数即可实现。

将上述查询结果设为临时表 e ,则 SQL 的书写方法:

select 在线时间段,count(角色id) as 玩家人数
from e
group by 在线时间段;

将临时表 e 的查询语句代入,则 SQL 的书写方法:

with d as
(with c as
(select a.角色id,a.日期,a.登录时间,(case when b.登出时间 is null then concat(a.日期,'23:59:59') else b.登出时间 end) as 登出时间
from
(select 角色id,日期,登录时间,rank() over(partition by 角色id,日期 order by 登录时间 asc) as 登录排名
from 登录日志) as a
left join
(select 角色id,日期,登出时间,rank() over(partition by 角色id,日期 order by 登出时间 asc) as 登出排名
from 登出日志) as b
on a.角色id = b.角色id and a.日期 = b.日期 and a.登录排名 = b.登出排名
)
select 角色id,日期,
sum(round((unix_timestamp(登出时间)- unix_timestamp(登录时间))/60,2)) as 总在线时长_min
from c
group by 角色id,日期
)
select 在线时间段,count(角色id) as 玩家人数
from
(select 角色id,(case when 总在线时长_min>=0 and 总在线时长_min<30 then '0-30min'when 总在线时长_min>=30 and 总在线时长_min<60 then '30min-1h'when 总在线时长_min>=60 and 总在线时长_min<120 then '1-2h'when 总在线时长_min>=120 and 总在线时长_min<180 then '2-3h'when 总在线时长_min>=180 and 总在线时长_min<300 then '3-5h'else '5h以上' end) as 在线时间段
from d
where 日期 = '2022-08-13'
) as e
group by 在线时间段;

查询结果如下:

2c024b6924b28ce1d7517277b4784aad.png

可以看到,虽然我们已经得到了各在线时间段的玩家人数,但是在线时间段的排列是乱序的,查看分布情况不是很方便。因此,我们需要对在线时间段进行重新排序。

「在线时间段」这一列数据类型为字符串,无法用 order by 子句进行简单排序,那么如何对在线时间段进行重新排序呢?

可以使用 field() 函数。field() 函数是自定义排序函数,可以自定义排列顺序,使用方法为:

order by field(值,str1,str2,str3,str4,……,strn) asc/desc

意思为:

将值按照 str1 , str2 , str3 , str4 ,……, strn 的顺序升序(asc)或者降序排列(desc)。

将其应用在本问题中,则为:

order by field(在线时间段,'0-30min','30min-1h','1-2h','2-3h','3-5h','5h以上') asc

即:将在线时间段这一列的值按照 '0-30min' , '30min-1h' , '1-2h' , '2-3h' , '3-5h' , '5h以上' 的顺序升序排列。

将其代入上述 SQL 语句中,则统计开服首日,玩家的在线时长分布的完整 SQL 的书写方法为:

with d as
(with c as
(select a.角色id,a.日期,a.登录时间,(case when b.登出时间 is null then concat(a.日期,'23:59:59') else b.登出时间 end) as 登出时间
from
(select 角色id,日期,登录时间,rank() over(partition by 角色id,日期 order by 登录时间 asc) as 登录排名
from 登录日志) as a
left join
(select 角色id,日期,登出时间,rank() over(partition by 角色id,日期 order by 登出时间 asc) as 登出排名
from 登出日志) as b
on a.角色id = b.角色id and a.日期 = b.日期 and a.登录排名 = b.登出排名
)
select 角色id,日期,
sum(round((unix_timestamp(登出时间)- unix_timestamp(登录时间))/60,2)) as 总在线时长_min
from c
group by 角色id,日期
)
select 在线时间段,count(角色id) as 玩家人数
from
(select 角色id,(case when 总在线时长_min>=0 and 总在线时长_min<30 then '0-30min'when 总在线时长_min>=30 and 总在线时长_min<60 then '30min-1h'when 总在线时长_min>=60 and 总在线时长_min<120 then '1-2h'when 总在线时长_min>=120 and 总在线时长_min<180 then '2-3h'when 总在线时长_min>=180 and 总在线时长_min<300 then '3-5h'else '5h以上' end) as 在线时间段
from d
where 日期 = '2022-08-13'
) as e
group by 在线时间段
order by field(在线时间段,'0-30min','30min-1h','1-2h','2-3h','3-5h','5h以上') asc;

查询结果如下:

032b038d0d6feae2fd21469290da0101.png

【本题考点】

1、考察逻辑分析能力,即:如何将复杂问题拆解成容易解决的一个个子问题的能力;

2、考察排序窗口函数的灵活使用。在需要进行分组排序时,排序窗口函数往往是首选;

3、考察 case when 语句的灵活应用以及分组汇总时,group by 子句、聚合函数的搭配使用;

4、考察纵向联结和横向联结的使用。纵向联结使用 union 方法(union、union all),横向联结使用 join 方法(left join、innerjoin、right join);

5、考察多重子查询的应用以及 with…as 语句的应用。

75a95b2604b8712eb433e133ff8ec625.jpeg

 ⬇️点击「阅读原文」

 免费报名 数据分析训练营

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/34228.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mfc 编辑框限制

DoDataExchange由框架调用&#xff0c;作用是交互并且验证对话框数据&#xff0c;主要由(DDX) 和 (DDV)宏实现。 永远不要直接调用这个函数&#xff0c;而是通过UpdateData(TRUE/FALSE)实现控件与变量之间值的传递。 当然你也可以不使用DoDataExchange而完成控件与变量之间值…

Python-组合数据类型

今天要介绍的是Python的组合数据类型 整理不易&#xff0c;希望得到大家的支持&#xff0c;欢迎各位读者评论点赞收藏 感谢&#xff01; 目录 知识点知识导图1、组合数据类型的基本概念1.1 组合数据类型1.2 集合类型概述1.3 序列类型概述1.4 映射类型概述 2、列表类型2.1 列表的…

java下载JDK

1.去官网下载 https://www.oracle.com/java/technologies/javase-downloads.html 2.点击 傻瓜式安装 注意选择版本跟电脑系统就行 下载后文件的作用

32个关于FPGA的学习网站

语言类学习网站 1、HDLbits 网站地址&#xff1a;https://hdlbits.01xz.net/wiki/Main_Page 在线作答、编译的学习Verilog的网站&#xff0c;题目很多&#xff0c;内容丰富。非常适合Verilog初学者&#xff01;&#xff01;&#xff01; 2、牛客网 网站地址&#xff1a;https:…

Flink CDC系列之:TiDB CDC 导入 Elasticsearch

Flink CDC系列之&#xff1a;TiDB CDC 导入 Elasticsearch 一、通过docker 来启动 TiDB 集群二、下载 Flink 和所需要的依赖包三、在TiDB数据库中创建表和准备数据四、启动Flink 集群&#xff0c;再启动 SQL CLI五、在 Flink SQL CLI 中使用 Flink DDL 创建表六、Kibana查看Ela…

不知道打仗之害,就不知道打仗之利

不知道打仗之害&#xff0c;就不知道打仗之利 【安志强趣讲《孙子兵法》第7讲】 【原文】 夫钝兵挫锐&#xff0c;屈力殚货&#xff0c;则诸侯乘其弊而起&#xff0c;虽有智者&#xff0c;不能善其后矣。 【注释】 屈力殚货&#xff1a;屈力&#xff0c;指力量消耗&#xff0c;…

工业巡检ar沉浸式互动培训体验实现更加直观、生动的流程展示

以往的工业手工巡检效率极低&#xff0c;错误率偏高&#xff0c;漏检问题严重&#xff0c;会因为现场人员对机械设备的早期维护、操作不会&#xff0c;而影响正常交付和服务&#xff0c;智慧工业是工业智能化和信息化的重要体现&#xff0c;在巡检方面自然也要同步提升&#xf…

使用Vue Query来获取数据

使用Vue Query来获取数据 构建现代大规模应用程序最具挑战性的方面之一是数据获取。加载和错误状态、分页、过滤、排序、缓存等功能会增加复杂性&#xff0c;并且经常会因大量样板代码而使应用程序变得臃肿。 vue query使用声明性语法处理和简化数据获取&#xff0c;并在幕后…

维深(Wellsenn):2023中国消费端VR内容开发商调研报告(附下载

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 国内互联网大厂商入局VR&#xff0c;字节跳动、网易表态明确。字节跳动2021年收购国内头部VR硬件厂商PICO后&#xff0c;加速构建VR内容生态&#xff0c;2021年 成立海南创见未来当前已推出VR视频应用…

大语言模型之三 InstructGPT训练过程

大语言模型 GPT历史文章中简介的大语言模型的的发展史&#xff0c;并且简要介绍了大语言模型的训练过程&#xff0c;本篇文章详细阐述训练的细节和相关的算法。 2020年后全球互联网大厂、AI创业公司研发了不少AI超大模型&#xff08;百亿甚至千亿参数&#xff09;&#xff0c;…

【C语言】结构体(1)

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C语言的结构体&#xff08;初阶&#xff09;&#xff0c;以后会出进阶的&#xff0c;如果大家觉得我写的不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 ① WHO IS 结构体② 结构体的作…

【学习日记】【FreeRTOS】手动任务切换详解

前言 本文是关于 FreeRTOS 中实现两个任务轮流切换并执行的代码详解。目前不支持优先级&#xff0c;仅实现两个任务轮流切换。 一、任务的自传 任务从生到死的过程究竟是怎么样的呢&#xff1f;&#xff08;其实也没死&#xff09;&#xff0c;这个问题一直困扰着我&#xf…

LeetCode[164]最大间距

难度&#xff1a;Hard 题目&#xff1a; 给定一个无序的数组 nums&#xff0c;返回 数组在排序之后&#xff0c;相邻元素之间最大的差值 。如果数组元素个数小于 2&#xff0c;则返回 0 。 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 示例 1: 输入: …

nacos 403错误

403错误 2023-08-12 18:04:55,418 [main] ERROR [com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder:106] [trace,span,parent] - get data from Nacos error,dataId:gateway-server.yaml, com.alibaba.nacos.api.exception.NacosException: <html><body&…

CSDN 直播:腾讯云大数据 ES 结合 AI 大模型与向量检索的新一代云端检索分析引擎 8月-8号 19:00-20:30

本次沙龙围绕腾讯云大数据ES产品展开&#xff0c;重点介绍了腾讯云ES自研的存算分离技术&#xff0c;以及能与AI大模型和文本搜索深度结合的高性能向量检索能力。同时&#xff0c;本次沙龙还将为我们全方位介绍腾讯云ES重磅推出的Elasticsearch Serverless服务&#xff0c;期待…

【BASH】回顾与知识点梳理(十六)

【BASH】回顾与知识点梳理 十六 十六. 十二至十五章知识点总结及练习16.1 总结16.2 练习16.3 简答题 该系列目录 --> 【BASH】回顾与知识点梳理&#xff08;目录&#xff09; 十六. 十二至十五章知识点总结及练习 16.1 总结 绝对路径&#xff1a;『一定由根目录 / 写起』…

permission denied while trying to connect to the Docker daemon socket 错误

安装 docker 执行错误如下&#xff1a; $ docker pspermission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get “http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json”: dial unix /var/run/docker.sock: connect:…

基于亚奈奎斯特采样和SOMP算法的平板脉冲响应空间插值matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...................................................................... %fine regular gr…

本地构建包含java和maven的镜像

目录 1.前提条件 2.下载 2.1.创建Dockerfile 3.构建镜像 参考文章 1.前提条件 本地环境需要的系统和软件 win10 Docker Desktop Powershell 图1 Win10安装Docker后&#xff0c;直接在Powershell使用Docker命令 有些Developer不习惯win10系统&#xff0c;却想要使用Lin…