顾乔芝士网

持续更新的前后端开发技术栈

LeetCode题解550. 游戏玩法分析 IV

刷刷题,leetcode的550题。

表定义如下:

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| player_id    | int     |
| device_id    | int     |
| event_date   | date    |
| games_played | int     |
+--------------+---------+
(player_id,event_date)是此表的主键(具有唯一值的列的组合)。
这张表显示了某些游戏的玩家的活动情况。
每一行是一个玩家的记录,他在某一天使用某个设备注销之前登录并玩了很多游戏(可能是 0)。

编写解决方案,报告在首次登录的第二天再次登录的玩家的 比率,四舍五入到小数点后两位。换句话说,你需要计算从首次登录日期开始至少连续两天登录的玩家的数量,然后除以玩家总数。

初次一看题目,使用左连接left join ,把用户id和日期作为关联条件,再去重。简单写出第一版语句:

SELECT ROUND(
(SELECT COUNT(distinct a.player_id) FROM activity a 
join activity b
on a.player_id = b.player_id
and a.event_date = ADDDATE(b.event_date, 1))
/ 
(SELECT COUNT(DISTINCT player_id) FROM activity)
,2) fraction ;

自信满满的提交,满心期待绿色的通过。结果很很打脸了,测试案例第6个没过。


老老实实把案例数据搞下来,跑跑看。

想用ai工具,把这个.md案例数据转成sql,失败了。可能是数据量太大了。





好吧,那就自己编码转成sql吧。

public void Case550()
{
    var mdfile = @"D:\xxx\LeetCodeCase\case550\case6.md";
    var sqlfile = @"D:\xxx\LeetCodeCase\case550\case6.sql";
    var mdTxtArr = File.ReadAllLines(mdfile);
    var sqlBuilder = new StringBuilder();
    sqlBuilder.AppendLine("INSERT INTO Activity (player_id, device_id, event_date, games_played) VALUES");
    foreach (var item in mdTxtArr)
    {
        var arr = item.Trim('|').Split('|');
        if (arr.Length >= 4)
        {
            var val = #34;({arr[0].Trim()}, {arr[1].Trim()}, '{arr[2].Trim()}', {arr[3].Trim()}),";
            sqlBuilder.AppendLine(val);
        }
    }
    var sqlTxt = sqlBuilder.ToString();
    File.WriteAllText(sqlfile, sqlTxt);
}

把结果导进去后,再仔细读题目。发现自己漏了关键信息“首次登录”。整理思路,先把首次登录的用户和日期筛选出来,再关联原表,把结果相除。代码如下:

SELECT ROUND( COUNT(distinct t.player_id) / COUNT(distinct tb.player_id),2) fraction
 FROM  (
SELECT player_id 
,MIN(event_date) first_date 
FROM activity 
GROUP BY player_id
) AS tb
LEFT JOIN activity t
ON tb.player_id = t.player_id
AND tb.first_date = ADDDATE(t.event_date, -1)

再次提交,成功。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言