#LC 550. 游戏玩法分析 IV
列名 | 类型 |
---|---|
player_id | int |
device_id | int |
事件日期 | 约会 |
玩过的游戏 | int |
(player_id, event_date) 是这个表的主键。 此表显示了某些游戏的玩家活动。 每一行都是一个玩家的记录,该玩家在某天使用某种设备注销之前登录并玩了很多游戏(可能是 0)。
Request:编写一个SQL查询来报告玩家在第一次登录的次日再次登录的比例,四舍五入到小数点后两位。换句话说,你需要计算从首次登录日期开始至少连续两天登录的玩家人数,然后用该数字除以玩家总数。
player_id | device_id | 事件日期 | 玩过的游戏 |
---|---|---|---|
1 | 2 | 2016-03-01 | 5 |
1 | 2 | 2016-03-02 | 6 |
2 | 3 | 2017-06-25 | 1 |
3 | 1 | 2016-03-02 | 0 |
3 | 4 | 2018-07-03 | 5 |
分数 |
---|
0.33 |
下面是我的代码(SQL Server):
with cte1 as (
select a1.player_id as player_id
from activity a1
right join activity a2
on dateadd(day, 1, a1.event_date) = a2.event_date
)
select round(count(distinct cte1.player_id)/count(distinct activity.player_id), 2) as fraction
from activity, cte1
结果应该是0.33,但我得到了0。可能是因为从两个表中选择(可以单独工作)。如果有人能帮助我理解为什么它是错误的,我将不胜感激。非常感谢!
乘以
1.0
将自动将count() (int)
转换为十进制。
select round(count(distinct cte1.player_id) * 1.0/count(distinct activity.player_id) * 1.0, 2) as fraction
from activity, cte1
你的尝试实际上并不太远。
当除法的所有操作数都是整数时,您的 DBMS 可能会进行整数除法。向上转换至少一个操作数,例如乘以
1.0
.
但是另外尝试左连接,这通常更容易理解和编写。你只需要一个连接,而你在外层加入 CTE and
SELECT
.
还建议在
JOIN
子句中始终使用明确的 FROM
语法而不是逗号。明确的JOIN
语法通常更容易理解和编写而不会出错。
SELECT round(count(DISTINCT a2.player_id) * 1.0
/
count(DISTINCT a1.player_id) * 1.0,
2) AS fraction
FROM activity a1
LEFT JOIN activity a2
ON a1.player_id = a2.player_id
AND a1.event_date = dateadd(day, -1, a2.event_date);
db<>fiddle(假设是 SQL Server)
#以上答案仅适用于少数测试用例。所以,这是正确的答案。
带DT AS ( 从 Activity GROUP BY PLAYER_ID 中选择 PLAYER_ID,MIN(EVENT_DATE) MIN_DATE ) , 金融时报 ( 选择 PLAYER_ID,EVENT_DATE 从 (SELECT PLAYER_ID, EVENT_DATE, ROW_NUMBER() OVER (PARTITION BY PLAYER_ID ORDER BY EVENT_DATE) 作为活动的 RK)A 其中 RK = 2) SELECT CONVERT(DECIMAL(6,2),COUNT(DT.player_id)*1.0/(SELECT COUNT(DISTINCT player_id) FROM Activity)) AS FRACTION FROM DT 在 DT.player_id= FT.player_id 上左加入 FT WHERE DATEDIFF(DAY, MIN_DATE, FT.event_date) = 1