累积型计算套路
# 534. 游戏玩法分析 III(难度:<font color=orange>**中等**</font>)
<img src="https://cos.easydoc.net/17082933/files/kegiqlho.png" style="zoom: 75%;" />
(player_id,event_date)是此表的主键。 这张表显示了某些游戏的玩家的活动情况。 每一行是一个玩家的记录,他在某一天使用某个设备注销之前登录 并玩了很多游戏(可能是 0 )。
编写一个 SQL 查询,同时报告每组玩家和日期,以及玩家到目前为止玩了多 少游戏。也就是说,在此日期之前玩家所玩的游戏总数。详细情况请查看示 例。
查询结果格式如下所示:
<img src="https://cos.easydoc.net/17082933/files/kegipjm2.png" style="zoom: 75%;" />
<img src="https://cos.easydoc.net/17082933/files/kegiq44o.png" style="zoom: 75%;" />
对于 ID 为 1 的玩家,2016-05-02 共玩了 5+6=11 个游戏, 2017-06-25 共玩了 5+6+1=12 个游戏。 对于 ID 为 3 的玩家,2018-07-03 共玩了 0+5=5 个游戏。 请注意,对于每个玩家,我们只关心玩家的登录日期。
**解法:**
**(1)联合查询**
```sql
SELECT
a1.player_id,
a1.event_date,
SUM(a2.games_played) AS games_played_so_far
FROM
Activity AS a1,
Activity AS a2
WHERE
a1.player_id = a2.player_id AND
a1.event_date >= a2.event_date
GROUP BY a1.player_id, a1.event_date
```
**(2)变量法–速度最快**
```sql
select
a.player_id,
a.event_date,
case
when @prev = a.player_id then @cnt := @cnt + a.games_played
when (@prev := a.player_id) is not null then @cnt := a.games_played
end games_played_so_far
from
Activity a,
(select @cnt := 0,@prev := null
) t
order by
a.player_id,
a.event_date
```
**(3)窗口函数–速度最慢**
```sql
select
player_id,
event_date,
sum(games_played) over(partition by player_id order by event_date) games_played_so_far
from Activity
```