结合常见游戏业务分析场景应用SQL实例(持续更新ing...)

前言:

  1. 本篇进阶练习题均来自真实的业务需求场景,SQL难度不高,但要求较为清晰的业务逻辑和对游戏项目的深入了解。
  2. 如果对于SQL不熟悉可以看我的这两篇文章:
  1. 数据本身已作脱敏处理,不可尽信。
例1:

数值策划想验证线上版本新玩家的升级和破产情况是否符合设计预期,故需查找2020.1.1-2020.2.5期间玩家首次破产时的等级的平均值,并区分应用版本$app_version、iOS和GooglePlay渠道channel。
由于存在一些小bug会导致部分玩家经验曲线有问题,所以只筛选首次破产在100级以下的玩家,以避免极端值影响平均值的计算。

数据表及字段如下:

	/*events表*/
	user_id		event		lv		date		channel				$app_version
	-----------------------------------------------------------------------------
	玩家id		事件名		等级	日期		iOS或GooglePlay		应用版本
	NUMBER		STRING		NUMBER	DATE		STRING				STRING
	-----------------------------------------------------------------------------
	111			Loading		1		2020-01-01	iOS					5.3.1
	222			EnterGame	2		2020-01-01	iOS					5.3.11
	333			Click_1		2		2020-01-01	GooglePlay			5.2.10
	333			Bankruptcy	28		2020-02-01	GooglePlay			5.3.1
	...			...			...		...			...					...
	
	/*users表*/
	id			channel				lv			user_group_3		user_group_10
	------------------------------------------------------------------------------
	玩家id		iOS或GooglePlay		等级		用户分群1			用户分群2
	NUMBER		STRING				NUMBER		BOOL				BOOL	
	------------------------------------------------------------------------------
	111			iOS					46			0					1
	222			iOS					149			0					1
	333			GooglePlay			87			1					1
	444			GooglePlay			34			0					0
	... 		   ...              ...        ...                 ...

注:

  • users表中的user_group_10是事先已定义好分群的研究对象,取值为真时生效。user_group_3是测试机分群,取值为假时生效。

参考语句:

	select channel,$app_version,avg(minlv) from 
		  (select user_id,min(events.lv) as minlv
		  	from users,events
			where events.user_id = users.id 
			and event = 'Bankruptcy' 
			and events.channel in ('iOS','GooglePlay')
			and date between '2020-01-01' and '2020-02-05'
			and user_group_10 = 1 and user_group_3 = 0
			group by user_id
			having minlv <= 100)a
	left join
		(select user_id,events.channel,$app_version,events.lv
		  from users,events
		  where events.user_id = users.id 
		  and event = 'Bankruptcy' 
		  and events.channel in ('iOS','GooglePlay')
		  and date between '2020-01-01' and '2020-02-05'
		  and user_group_10 = 1 and user_group_3 = 0)b
	on a.minlv = b.lv and a.user_id = b.user_id
	group by channel,$app_version
例2:

礼包促销期间,玩家反馈自己购买的礼包并没有如宣传弹窗上所说得到双倍金币。经查证打点信息,该名玩家的确花了$29.99购买了原价礼包,且版本更新到了最新版本,即能下载到活动热更。
现在想统计购买同类型礼包的玩家中,有多少玩家遇到与该玩家相同的情形及占比,以便确认补偿方式,是由运营极个别手动补充,还是需要服务端程序写脚本批量补充,或者干脆对全体付费玩家补偿。
同时为了帮助开发人员定位问题所在,所以按版本查看,看是哪个版本开始出现问题。

数据表及字段如下:

	/*events表*/
	user_id		event		str2		str9		    date		channel				$app_version
	------------------------------------------------------------------------------------------------
	玩家id		事件名		商品id		是否促销			日期		iOS或GooglePlay		应用版本
	NUMBER		STRING		STRING		STRING			DATE		STRING				STRING
	------------------------------------------------------------------------------------------------
	111			Loading									2020-01-01	iOS					3.8.0
	222			Buy	   		6			False			2020-01-01	iOS					3.7.0
	333			Click_1									2020-01-01	GooglePlay			3.7.0
	333			Buy			49			True			2020-02-01	GooglePlay			3.6.0
	...			...			...		...			...					...

注:

  • 由于埋点时没注意,促销礼包商品id定义成了STRING格式,id在0~6之间,以及48以上的属于和该玩家同类型的礼包。

参考语句:

	select $app_version,str9,sum(num) from(
			select $app_version,str9,str2,count(event) as num
			from events
			where event = 'Buy' 
			and channel in ('iOS','GooglePlay') 
			and $app_version in  (‘3.6.0’, '3.7.0','3.8.0','3.9.0')
			and date >= '2020-02-25' and date <= '2020-02-29'
			group by $app_version,str9,str2
			order by str9)a
	where cast(str2 as integer) > 48 or cast(str2 as integer) <= 6
	group by $app_version,str9
	order by $app_version,str9
例3:

某款游戏做了关于前期关卡难度的AB测试,现需评估AB版本的关卡难度是否符合我们的预期

关卡难度用过关率和通关率评估,其中

	通关率 = 该关卡通关人数 / 该关卡挑战总人数
	过关率 = 该关卡过关次数(不含c道具) /  该关卡挑战总次数

在此需要说明的几点:

  • 过关率原则上需使用 该关卡过关次数(不含任何道具) / 该关卡挑战总次数 (不含任何道具)来进行计算。但由于后期关卡难度较大,若玩家不使用道具则难以通关,从而造成样本量过小而过关率数据失去意义。在这个栗子中,道具c的使用对过关率数据影响最大,且严格来讲玩家只有在通关失败时才会触发道具c的使用,因此使用道具c通关也视为失败,这里需排除使用道具c打通关的情形;
  • 通关率能从侧面反映卡级和关卡流失人数;

涉及的事件、字段及其含义如下:

	/*events表*/
	user_id		event		date		level		version		int1
	-----------------------------------------------------------------
	玩家id  	事件名  		日期    	关卡id  	游戏版本   是否使用道具c
	NUMBER 		STRING  	DATE	    NUMBER  	STRING		NUMBER
	-----------------------------------------------------------------
	7863	   LevelStart	2019-08-28		12		 2.1.10								
	7937	   LevelStart	2019-08-28		34	 	 2.1.10
	7389	   LevelSuccess	2019-08-28		14		 2.1.10			0
	7863	   LevelSuccess	2019-08-28		12		 2.1.10			1
	7364	   LevelFail	2019-08-28		56		 2.1.10			1
	...  		... 			... 		... 	   ... 		   ...

	/*users表*/
	id				user_group_50		abtest_id
	----------------------------------------------
	玩家id			用户分群				ab版本号	
	NUMBER			BOOL				STRING
	----------------------------------------------	
	7863				1					a
	7937				0					a
	7389				1					b
	7364				1					a
	...				   ...				   ...

注:
Ⅰ. events表中只有LevelSuccess/LevelFail有int1字段信息,LevelStart的int1字段为空;int1 = 1表示使用了道具c,int1 = 0表示未使用道具c;
Ⅱ. users表中的user_group_50为选定时间段内的新玩家分群,这个分群已排除了测试机、老用户换新设备等数据干扰,写SQL时选择user_group_50的值为真即可;
Ⅲ. users表中的abtest_id仅有两种取值,a和b,分别代表a版本和b版本;

参考语句:

  • a版本的过关率统计

      select T1.level,T1.LevelTry,T2.LevelPass,levelpass/leveltry as SuccessRate,T1.PlayerNum 
      from 
      	(select level, count(event)as LevelTry,count(distinct user_id)as PlayerNum
      	 from events 
      	 where event ='LevelStart' and version = '2.1.10'
      	 and date >= '2019-08-28' 
      	 and user_id in 
      		(select id from users where user_group_50 = 1
      		 and abtest_id = 'a')
             group by level) as T1 
      left join 
       	(select level, count(event)as LevelPass from events 
       	 where event ='LevelSuccess' and version = '2.1.10' and int1 = 0
       	 and date >= '2019-08-28'
       	 and user_id in 
       		(select id from users where user_group_50 = 1
       		 and abtest_id = 'a')
             group by level) as T2
      on T1.level = T2.level
      order by level
    
  • a版本的通关率统计

      select T1.level,T1.LevelEnter,T2.LevelPass, levelpass/levelenter as Passrate
      from 
      	(select level, count(distinct user_id)as LevelEnter from events 
      	 where event = 'LevelStart' and version = '2.1.10'
      	 and date>= '2019-08-28'
      	 and user_id in 
      	 	(select id from users where user_group_50 = 1
      	 	 and abtest_id = 'a')
      	 	 group by level) as T1 
      left join 
      	(select level, count(distinct user_id)as LevelPass from events 
      	 where event ='LevelSuccess' and version = '2.1.10'
      	 and date>= '2019-08-28'
      	 and user_id in 
      	 	(select id from users where user_group_50 = 1
      	 	 and abtest_id = 'a')
      	 	 group by level) as T2
      on T1.level = T2.level 
      order by T1.level
    
  • b版本的过关率&通关率统计同上,只需将users表中abtest_id字段的值改为b,其SQL语句略

例4:

通过每日数据监测,发现某款游戏收入异常下跌。对照异常数据始发时间和多维度分析,定位为4.3.1版本发布后出现的问题。按照业务经验推测,收入异常下跌往往和游戏内资产失衡挂钩,check玩家资产监测数据,果真发现4.3.1版本发布后玩家资产上涨异常。
现需找出这部分资产上涨异常的玩家行为事件,请数值策划确认是否有BUG
(资产上涨异常视具体游戏而定,这里的资产上涨异常定义为前3~2d每日首次登录资产数不足1kw的玩家,在昨日资产上涨2个数量级,即超过10亿。这在数值设计看来是不合理的。)

数据表形式如下:

/*events表*/
user_id		event		time		payamount		coins		lv		viplevel	str0		str1		str2		str3		int0		int1		int2		int3		double0		version
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
玩家id  	事件名	    时间   		累计付费额  		虚拟资产		等级	vip等级		str0		str1		str2		str3		int0		int1		int2		int3		double0		游戏版本
NUMBER      STRING     DATETIME	      NUMBER        NUMBER    NUMBER	 NUMBER	   STRING		STRING		STRING		STRING		NUMBER		NUMBER		NUMBER		NUMBER		NUMBER		STRING
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8977		loading		2020-04-03		0			93038272	132			0																	  1												4.3.1			
7383		Loading		2020-04-03		0			73839282233	68			0																	  0												4.2.5
7223		Pay			2020-04-04		99.99		73822		456			3																	  0									4.99		4.3.1
7362		Click_1		2020-04-04		0			32202746	7			0																	  0												4.2.4
8383		Click_2		2020-04-04		19.89		8472822		31			1																	  0												4.2.4
7364		Loading		2020-04-05		0			17374		98			0																	  1												4.3.1
...			...			...				...			...			...		...			...			...			...			...			...			...			...			...			...			...

注:

  • str0 ~ str3,int0 ~ int3在不同的event中表示不同的含义;在玩家登录,即Loading事件中, 仅int1字段有值,表示玩家当日第几次登录游戏,int1 = 1表示玩家当日首次登录游戏;

参考语句:

select user_id, event, time, payamount, coins, lv, viplevel,
str0, str1, str2, str3,  int0, int1, int2, int3, double0, version
from events
where user_id in 
	(select user_id from events 
	 where event =  'Loading' and int1 = 1 
	 and coins > power(10, 9)
	 and date = CURRENT_DATE() - INTERVAL '1' DAY
	 and user_id in 
	 			(select user_id from events 
	 			 where event =  'Loading' and int1 = 1 
	 			 and credit < power(10, 7)
	 			 and date between CURRENT_DATE() - INTERVAL '3' DAY and CURRENT_DATE() - INTERVAL '2' DAY
	 			 )
	 )
and date >= CURRENT_DATE() - INTERVAL '3' DAY
ORDER BY user_id, time
例5:

待更新。。。

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值