题目描述
(通过次数23,825 | 提交次数34,947,通过率68.17%)
Table:Activity +--------------+---------+ | Column Name | Type | +--------------+---------+ | player_id | int | | device_id | int | | event_date | date | | games_played | int | +--------------+---------+ (player_id,event_date)是此表的主键。 这张表显示了某些游戏的玩家的活动情况。 每一行是一个玩家的记录,他在某一天使用某个设备注销之前登录并玩了很多游戏(可能是 0 )。 编写一个 SQL 查询,同时报告每组玩家和日期,以及玩家到目前为止玩了多少游戏。也就是说,在此日期之前玩家所玩的游戏总数。详细情况请查看示例。 查询结果格式如下所示: Activity table: +-----------+-----------+------------+--------------+ | player_id | device_id | event_date | games_played | +-----------+-----------+------------+--------------+ | 1 | 2 | 2016-03-01 | 5 | | 1 | 2 | 2016-05-02 | 6 | | 1 | 3 | 2017-06-25 | 1 | | 3 | 1 | 2016-03-02 | 0 | | 3 | 4 | 2018-07-03 | 5 | +-----------+-----------+------------+--------------+ Result table: +-----------+------------+---------------------+ | player_id | event_date | games_played_so_far | +-----------+------------+---------------------+ | 1 | 2016-03-01 | 5 | | 1 | 2016-05-02 | 11 | | 1 | 2017-06-25 | 12 | | 3 | 2016-03-02 | 0 | | 3 | 2018-07-03 | 5 | +-----------+------------+---------------------+ 对于 ID 为 1 的玩家,2016-05-02 共玩了 5+6=11 个游戏,2017-06-25 共玩了 5+6+1=12 个游戏。 对于 ID 为 3 的玩家,2018-07-03 共玩了 0+5=5 个游戏。 请注意,对于每个玩家,我们只关心玩家的登录日期。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/game-play-analysis-iii
//测试数据 Create table If Not Exists Activity (player_id int, device_id int, event_date date, games_played int); insert into Activity (player_id, device_id, event_date, games_played) values ('1', '2', '2016-03-01', '5'); insert into Activity (player_id, device_id, event_date, games_played) values ('1', '2', '2016-05-02', '6'); insert into Activity (player_id, device_id, event_date, games_played) values ('1', '3', '2017-06-25', '1'); insert into Activity (player_id, device_id, event_date, games_played) values ('3', '1', '2016-03-02', '0'); insert into Activity (player_id, device_id, event_date, games_played) values ('3', '4', '2018-07-03', '5');
解题思路
本题68.17%的通过率,难度中等。一般稍微思考一下,就能找到思路。
这是一道典型的求累计值的题目。
既然题目要求,计算某一天之前所有的games_played之和,那么是不是可以将这天之前的记录,都归集到这一天来,然后再汇总求和呢?
不过,怎么将这天之前的记录,都归集到这一天?
可以使用如下的自关联来实现:
select a.player_id, a.event_date, b.games_played from Activity a inner join Activity b on a.player_id = b.player_id and a.event_date >= b.event_date;
这样就能把每一个玩家,每一个event_date之前的记录归集到这一天来了。
之后的汇总统计就比较简单了。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select a.player_id, a.event_date, sum(b.games_played) as games_played_so_far from Activity a inner join Activity b on a.player_id = b.player_id and a.event_date >= b.event_date group by a.player_id,a.event_date order by a.player_id,a.event_date;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。