SQL 查询为我提供了每天无法运行游戏的用户百分比

Posted

技术标签:

【中文标题】SQL 查询为我提供了每天无法运行游戏的用户百分比【英文标题】:SQL query that gives me the percentage of users that fail to run a game per day 【发布时间】:2020-02-12 14:29:43 【问题描述】:

对于我一直在努力编写的 SQL 查询,我非常感谢。

背景

每次用户玩游戏时,都会在表game_runs 中创建一条记录,以及他们的user_idrun_datemysql 时间戳)。

当用户成功玩游戏时,他们得到大于 0 的分数。 如果游戏运行失败(例如可能崩溃),则得分为0

表格如下所示:

 id  |     run_date         |  user_id   |   score   
-------------------------------------------------------
 1   |  2020-02-02 00:20:00 |    10      |     0      |   
 2   |  2020-02-02 01:50:10 |    10      |    40      |   
 3   |  2020-02-02 03:40:20 |    11      |    80      |   

 4   |  2020-02-03 03:20:14 |    20      |    80      |   
 5   |  2020-02-03 12:20:14 |    21      |     0      |   

 6   |  2020-02-04 06:20:42 |    50      |     0      |   
 7   |  2020-02-04 11:15:00 |    50      |     0      |
 8   |  2020-02-04 12:10:46 |    51      |    70      |   

 9   |  2020-02-05 00:15:00 |    60      |     0      |
10   |  2020-02-05 01:10:40 |    61      |     0      |   

我想知道每天有多少百分比的用户无法运行游戏。

在上面的例子中,这是我希望我能生成的:

date         |   percent_users_who_failed_to_run_the_game
-------------------------------------------------------------
2020-02-02   |   0
2020-02-03   |   0.5
2020-02-04   |   0.5
2020-02-05   |   1

注意2020-02-02 上,运行游戏失败的用户百分比为 0%(即每个人都至少成功了一次)。这是因为在 2020-02-02 上运行了 3 次:

id=1: user_id 10 初始运行失败(分数=0) id=2:user_id10第二次成功(score=40) id=3: user_id 11 成功

由于当天两个用户都成功了,因此失败的用户百分比为 0%。

我很想知道如何开始。我正在使用 mySQL v8+,因此可以在必要时访问窗口函数(我的研究告诉我,它们可能会有所帮助,但无法编写执行此操作的查询)。

我认为正确的逻辑是找出拥有​​MAX(score) = 0 但不确定如何编写查询的用户的百分比。

我希望这不是太不清楚 - 非常感谢您到目前为止的阅读,任何指示都会很有帮助。

谢谢!

【问题讨论】:

见:Why should I provide an MCRE for what seems to me to be a very simple SQL query? 【参考方案1】:

我认为您需要分两步执行此操作。第一步是获取每位用户每天的最高分:

SELECT  CAST(Run_Date AS DATE) AS RunDate,
        User_ID,
        MAX(Score) AS Score
FROM    YourTable
GROUP BY CAST(Run_Date AS DATE), User_ID;

然后你可以把它放在一个子查询中并计算你的百分比:

SELECT  RunDate,
        COUNT(CASE WHEN Score = 0 THEN 1 END) / SUM(1.0) AS Failed_Percent
FROM    (   SELECT  CAST(Run_Date AS DATE) AS RunDate,
                    User_ID,
                    MAX(Score) AS Score
            FROM    YourTable
            GROUP BY CAST(Run_Date AS DATE), User_ID
        ) AS t
GROUP BY RunDate;

Example on SQL Fiddle

您也可以在不使用子查询的情况下使用COUNT(DISTINCT)

SELECT  CAST(Run_Date AS DATE) AS RunDate,
        1 - (1.0 * COUNT(DISTINCT CASE WHEN Score > 0 THEN User_ID END) 
            / COUNT(DISTINCT User_id)) AS Failed_Percent
FROM    YourTable
GROUP BY CAST(Run_Date AS DATE);

Example on SQL Fiddle

这确实是在做相反的逻辑,但是结果是一样的。相关部分是:

COUNT(DISTINCT CASE WHEN Score > 0 THEN User_ID END)

这将获取在任何给定日期成功运行游戏的不同用户总数,然后

COUNT(DISTINCT User_id) 

提供在该日期记录记录的用户总数。前者除以后者得出成功用户的百分比,因此我们需要从 1 中减去它以获得失败的百分比。我已将其中一个计数乘以 1.0 以将其隐式转换为小数以避免integer division

我希望第一个查询更有效率,但我可能错了。

【讨论】:

哇,非常感谢加雷斯!我运行了两个查询,你是对的,子查询确实更有效。【参考方案2】:

你可以在没有子查询的情况下做到这一点:

select date(run_date) as dte,
       1 - count(distinct case when score > 0 then user_id end)) / count(distinct user_id)
from t
group by dte;

这会计算每天成功运行游戏的用户数量。 1 - <this amount> 是不成功的号码。

【讨论】:

以上是关于SQL 查询为我提供了每天无法运行游戏的用户百分比的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery - 为我的帐户上未运行的查询计费

每天在 Mondrian MDX 中获取用户数量

将为我提供每个 senderId 的最新 messageContent 帖子的 SQL 查询是啥?

SQL 百分位数计算运行非常缓慢 - 需要帮助加快速度

如何安排作业以每天运行 SQL 查询?

通过 Firebase 分析获取非活动用户的百分比