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_id
和run_date
(mysql 时间戳)。
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 次:
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 查询为我提供了每天无法运行游戏的用户百分比的主要内容,如果未能解决你的问题,请参考以下文章