sql架构
Create table If Not Exists Activity (player_id int, device_id int, event_date date, games_played int) Truncate table Activity 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‘)
这张表显示了某些游戏的玩家的活动情况。
每一行是一个玩家的记录,他在某一天使用某个设备注销之前登录并玩了很多游戏(可能是 0 )
问题:
编写一个 SQL 查询,同时报告每组玩家和日期,以及玩家到目前为止玩了多少游戏。也就是说,在此日期之前玩家所玩的游戏总数。
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 个游戏。 请注意,对于每个玩家,我们只关心玩家的登录日期。
select t1.player_id,t1.event_date,sum(t2.games_played) games_played_so_far from Activity t1 inner join Activity t2 on t1.player_id = t2.player_id and t1.event_date >= t2.event_date group by t1.player_id,t1.event_date order by t1.player_id,t1.event_date
思路:
我们求的是每个玩家从第一天开始,到最后一天结束。每天统计:当天玩游戏次数+之前的所有天的玩游戏次数的总和。
首先,使用笛卡尔积,自连2个表。
然后,条件筛选,t1.event_date >= t2.event_date。??这个条件非常重要!理解它就理解了本题答案。
那么,以t1.even_date进行分组的话,sum(t2.games_played)就相当于累加了当天及之前数天的玩游戏的次数。
总结:
将每个人,在当前和之前几天玩过的游戏个数进行累加。
2个表自连接,筛选条件,group by。 使用累加和的方法解题。
使用Mysql8.0的window计算函数。
select player_id, event_date, sum(games_played) over(partition by player_id order by event_date asc rows UNBOUNDED PRECEDING ) as games_played_so_far from activity;
+-----------+------------+---------------------+ | 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 | +-----------+------------+---------------------+
window的frame语法使用:https://www.cnblogs.com/chentianwei/p/12145280.html
??代码也可以用
??好像range|rows是别名的关系。
使用if语句和@var进行逻辑判断和逻辑运算。不适合mysql5.7。分析不复杂,但代码写起来很复杂。
原文:https://www.cnblogs.com/chentianwei/p/12179445.html