你今天玩游戏了吗?游戏道具了解下

news/2024/10/30 17:18:25/

3435657f74d0377d5bc930e68a57acc7.png

【面试题】

某游戏的某促销活动,会向玩家推荐一个道具,同时会得到该道具的折扣券。折扣券无有效期,但购买道具一次后失效。推荐一个新的道具,也会导致旧的折扣券失效。

假设道具推荐、查看、购买行为记录在了下面的“游戏道具记录表”中,包含4个字段:时间、玩家id、行为、道具id。

02ce552d160df456d916f0ef16bc1d0f.png

表中的“行为”字段的值包括:向玩家推荐道具、玩家查看道具、玩家成功付费购买道具

数据说明:

 1)一个道具的折扣券失效后,玩家仍然可以以原价购买推荐的道具

 2)同一个道具不会被重复推荐

 3)如果玩家使用折扣券购买道具,则认为这次推荐道具->查看道具->购买道具属于一个成功推荐过程,推荐道具->购买道具(即中途缺少该道具的查看记录)不属于成功推荐过程。

 4)玩家可以推荐前查看道具,但不会获得折扣券

【问题】查询所有成功推荐过程中,该道具的第一条查看记录。

【解题步骤】

1. 解题思路

这个业务问题一看很复杂,遇到复杂的问题,要想到用逻辑树分析方法,将复杂问题拆解为可以解决的子问题:

1)找出所有成功推荐的记录(成功推荐是玩家使用折扣券进行购买)

7effe81734aa3d8b917f7761788e23f9.png

2)找出成功推荐时间与对应购买时间之间的查看记录

9b3c1248f73c1310832c91bcb634387f.png

3)筛选出每一次成功推荐的第一条查看记录

42fd3d1da6136c55414ef710db41f213.png

2. 所有成功推荐的记录

一次成功推荐是“推荐道具->查看道具->购买道具”这样的过程。

1)获取所有推荐道具的数据

select 时间,玩家id,行为,道具id
from 游戏道具记录表
where 行为 = '推荐道具';

记为表t1。

2)获取所有购买道具的数据

select 时间,玩家id,行为,道具id
from 游戏道具记录表
where 行为 = '玩家购买';

记为表t2。

3)获取同一个玩家同一个道具的“推荐道具->购买道具”

以“所有推荐道具的数据”为左表,使用左联结,从“所有购买道具的数据”中获取同一个玩家同一个道具的购买记录(购买时间在推荐时间之后)。

由于一次推荐之后,可能存在多次购买记录,此处使用窗口函数每次推荐之后对应的购买时间顺序。

select t1.玩家id,t1.时间 as 推荐道具时间,t1.道具id as 推荐道具id,t2.时间 as 玩家购买时间,t2.道具id as 玩家购买道具id,row_number() over(partition by t1.玩家id,t1.时间,t1.道具id order by t2.时间) as 玩家购买时间顺序
from t1
left join 
t2 on t1.玩家id = t2.玩家id and t1.道具id = t2.道具id
where t1.时间 < t2.时间;

查询结果:

5c9e04d03f602f84556b99d2d5693c3a.png

以上结果记为表t3。

4)对“玩家购买时间顺序”进行筛选

按照成功推荐的定义,“玩家购买时间顺序”为1时,才可能成为成功推荐。

因为,购买道具一次后道具对应的折扣券会失效。

select 玩家id,推荐道具时间,推荐道具id,玩家购买时间,玩家购买道具id
from t3
where 玩家购买时间顺序 = 1;

f58c87a758b9de252036b5879c3f0638.png

以上结果记为表tt1。

5)得到成功推荐的记录

上一步的结果还不是成功推荐。

因为,如果“推荐道具时间”与“玩家购买时间”之间有另外的一次推荐,这次的推荐的折扣券就失效了。

查询出“推荐道具时间”与“玩家购买时间”之间没有其他推荐的记录。

select tt1.玩家id,tt1.推荐道具时间,tt1.推荐道具id,tt1.玩家购买时间,tt1.玩家购买道具id
from tt1
left join t1 on tt1.玩家id = t1.玩家id and tt1.推荐道具时间 < t1.时间 and tt1.玩家购买时间 > t1.时间
where t1.行为 is null;

19eb4d5397f2cef02b569528ffad0481.png

以上结果记为数据a1。

3. 获取成功推荐中的查看记录

1)获取所有查看道具的数据

select 时间,玩家id,行为,道具id
from 游戏道具记录表
where 行为 = '玩家查看';

记为表a2。

2)获取成功推荐记录中“推荐道具时间”与“玩家购买时间”之间的所有查看记录

select a1.玩家id,a1.推荐道具时间,a1.推荐道具id,a1.玩家购买时间,a1.玩家购买道具id,a2.时间 as 玩家查看时间,a2.道具id as 玩家查看道具id,row_number() over(partition by a1.玩家id,a1.玩家购买时间,a1.玩家购买道具id order by a2.时间) as 查看时间顺序
from a1
left join 
a2 on a1.玩家id = a2.玩家id and a1.推荐道具id = a2.道具id
where a2.时间 > a1.推荐道具时间 and a2.时间 <= a1.玩家购买时间;

57553f806d5580120124de403253720b.png

同时,用窗口函数row_number()获取了“查看时间顺序”。

以上结果记为a3。

4. 获取成功推荐中的第一条查看记录

最后,筛选出第一次查看的记录,并恢复成初始的数据结构。

select 玩家查看时间 as 时间,玩家id,'玩家查看' as 行为,玩家查看道具id as 道具id
from a3
where 查看时间顺序 = 1;

将子查询代入:

select 玩家查看时间 as 时间,玩家id,'玩家查看' as 行为,玩家查看道具id as 道具id
from (
select a1.玩家id,a1.推荐道具时间,a1.推荐道具id,a1.玩家购买时间,a1.玩家购买道具id,a2.时间 as 玩家查看时间,a2.道具id as 玩家查看道具id,row_number() over(partition by a1.玩家id,a1.玩家购买时间,a1.玩家购买道具id order by a2.时间) as 查看时间顺序
from (
select tt1.玩家id,tt1.推荐道具时间,tt1.推荐道具id,tt1.玩家购买时间,tt1.玩家购买道具id
from (
select 玩家id,推荐道具时间,推荐道具id,玩家购买时间,玩家购买道具id
from (
select t1.玩家id,t1.时间 as 推荐道具时间,t1.道具id as 推荐道具id,t2.时间 as 玩家购买时间,t2.道具id as 玩家购买道具id,row_number() over(partition by t1.玩家id,t1.时间,t1.道具id order by t2.时间) as 玩家购买时间顺序
from (
select 时间,玩家id,行为,道具id
from 游戏道具记录表
where 行为 = '推荐道具'
) as t1
left join (
select 时间,玩家id,行为,道具id
from 游戏道具记录表
where 行为 = '玩家购买'
) as t2 on t1.玩家id = t2.玩家id and t1.道具id = t2.道具id
where t1.时间 < t2.时间
) as t3
where 玩家购买时间顺序 = 1
) as tt1
left join (
select 时间,玩家id,行为,道具id
from 游戏道具记录表
where 行为 = '推荐道具'
) as tt2 on tt1.玩家id = tt2.玩家id and tt1.推荐道具时间 < tt2.时间 and tt1.玩家购买时间 > tt2.时间
where tt2.行为 is null
) as a1
left join (
select 时间,玩家id,行为,道具id
from 游戏道具记录表
where 行为 = '玩家查看'
) as a2 on a1.玩家id = a2.玩家id and a1.推荐道具id = a2.道具id
where a2.时间 > a1.推荐道具时间 and a2.时间 <= a1.玩家购买时间
) as a3
where 查看时间顺序 = 1;

408c7d26dc6679f6c6e16b3d41958f9c.png

【本题考点】

1)考查对窗口函数的了解;

2)考查对多表联结的了解。

ae0c81ed61739185526234d48e3d0957.png

ffbe15b450b8464b97bf2a7f522b3a25.png

 ⬇️点击「阅读原文」

 免费报名 数据分析训练营


http://www.ppmy.cn/news/332858.html

相关文章

Nim 游戏 、⽯头游戏1、石头游戏2

Nim 游戏 、⽯头游戏1、石头游戏2 文章目录 Nim 游戏 、⽯头游戏1、石头游戏2**一&#xff1a;Nim 游戏****二&#xff1a;⽯头游戏****三、石头游戏2****方法一&#xff1a;DP 函数****方法二&#xff1a;DP table** 一&#xff1a;Nim 游戏 你和你的朋友&#xff0c;两个人一…

这有10款好玩游戏,游戏迷速来围观

1、我飞刀玩得贼6 一款创新玩法的游戏&#xff0c;通过对一大堆飞刀的熟练操控来进行混战&#xff0c;独创的龟缩防御机制&#xff0c;让你能轻松在对手面前秀一把。 2、监狱建筑师 它作为一款优秀的模拟游戏&#xff0c;沿袭了《地下城守护者》、《矮人要塞》以及《主题医院…

从0-1一起学习live555设计思想之二 RTSP交互过程

流媒体服务系列 文章目录 流媒体服务系列前言一、OPTION二、DESCRIBE三、SETUP四、PLAY总结前言 本篇文章通过代码去分析rtsp交互过程与工作原理。由于live555的继承关系太过复杂,所以做了个图简单记录一下与h264文件传输相关的类继承关系。 一、OPTION OPTION比较简单,就…

C语言基础--整型int,长整型long,浮点型double float

本文讲解常见的C语言变量,并举出一些实例 从微软的C语言文档把所有的C语言可定义(就是能用的)截图展示: 还有好几页,不放了,看着都头疼 但是,往往用的最多的,也就是下面的(本篇只讲整数和浮点数) int 整数 整数的定义不用说了吧QAQ int a = 10; //定义一个…

libVLC 调节图像(亮度、对比度、色调、饱和度、伽玛)

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 对于一个视频来说,色彩和画面效果的呈现非常重要。假如你的画面偏暗或偏亮,缺乏层次感,色彩不够丰富或不自然,则需要根据场景和氛围进行调整。 所涉及的重要参数有: 亮度: 是视频画面的明暗程度。调整…

shell脚本基础5——常用命令写作技巧

文章目录 一、grep命令二、sed命令2.1 选项参数2.2 常用命令 三、AWK命令3.1 常用参数3.2 常用示例 四、find与xargs五、date命令六、对话框6.1 消息框6.2 yes/no对话框6.3 表单输入框6.4 密码输入框6.5 菜单栏6.6 单选对话框6.7 多选对话框6.8 进度条 七、常用写作技巧7.1 EOF…

做副业的我很迷茫,但ChatGPT却治好了我——AI从业者被AI模型治愈的故事

迷茫&#xff0c;无非就是不知道自己要做什么&#xff0c;没有目标&#xff0c;没有方向。 当有一个明确的目标时&#xff0c;往往干劲十足。但做副业过程中&#xff0c;最大的问题往往就是 不知道自己该干什么。 干什么&#xff1f;怎么干&#xff1f;干到什么程度&#xff1f…

sm2,sm4加密(js+java)

一、使用 做项目时&#xff0c;首先采用了sm2数据传输加密&#xff0c;随后又改为sm4&#xff0c;此处使用仅为个人愚见&#xff0c;望与诸君共勉。 sm2,非对称加密&#xff0c;在后端生成两对秘钥&#xff0c;私钥A,公钥A,私钥B,公钥B。前端持有公钥A,私钥B&#xff0c;后端持…