下面是leetcode题
桌子:活动
列名 | 类型 |
---|---|
player_id | int |
device_id | int |
事件日期 | 约会 |
玩过的游戏 | int |
(player_id, event_date) 是这个表的主键。 此表显示了某些游戏的玩家活动。 每一行都是一个玩家的记录,该玩家在某天使用某种设备注销之前登录并玩了很多游戏(可能是 0)。
编写一个 SQL 查询来报告每个玩家和日期,玩家到目前为止玩了多少场比赛。也就是说,玩家在该日期之前玩的游戏总数。检查示例是否清晰。
按任意顺序返回结果表
查询结果格式如下例
Player_Id | Device_ID | 活动日期 | Games_Played |
---|---|---|---|
1 | 2 | 2016-03-01 | 5 |
1 | 2 | 2016-03-02 | 6 |
1 | 3 | 2017-06-25 | 1 |
3 | 1 | 2016-03-02 | 0 |
3 | 4 | 2018-07-03 | 5 |
我已经用Windows函数解决了。我的代码如下
select player_id,event_date,sum(games_played) over(partition by player_id order by event_date) as games_played_so_far from activity
和输出
player_id | 事件日期 | 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 |
但是在使用 JOIN 解决它时,我无法理解,为什么我们需要对 a2.games_played 而不是 a1.games_played 求和。代码如下
SELECT a1.player_id, a1.event_date ,SUM(a2.games_played) AS games_played_so_far
FROM activity a1, activity a2
WHERE a1.player_id = a2.player_id
AND a1.event_date >=a2.event_date
GROUP BY a1.player_id, a1.event_date
ORDER BY a1.player_id, a1.event_date;
并且,我编写了以下代码并得到了以下结果。如果看到下面的输出,则 a1_played 看起来对齐,而 a2_Played 仅包含 0 和 5 值。我不明白为什么我们要总结 a2_played
SELECT a1.player_id, a1.event_date as a1_Date, a2.event_date as a2_Date,a1.games_played as a1played,a2.games_played as a2played,
SUM(a1.games_played) AS sum_a1,SUM(a2.games_played) AS sum_a2
FROM activity a1, activity a2
WHERE a1.player_id = a2.player_id
AND a1.event_date >=a2.event_date
GROUP BY a1.player_id, a1.event_date
ORDER BY a1.player_id, a1.event_date;
Player_Id | a1_日期 | a2_日期 | a1_Played | a2_Played | sum_a1_Played | Sum_a2_Played |
---|---|---|---|---|---|---|
1 | 2016-03-01 | 2016-03-01 | 5 | 5 | 5 | 5 |
1 | 2016-05-02 | 2016-03-01 | 6 | 5 | 12 | 11 |
1 | 2017-06-25 | 2016-03-01 | 1 | 5 | 3 | 12 |
3 | 2016-03-02 | 2016-03-02 | 0 | 0 | 0 | 0 |
3 | 2018-07-03 | 2016-03-02 | 5 | 0 | 10 | 5 |
如果您使用您父亲的 SQL 而不是您祖父的 SQL 重写您的查询,即使用显式 JOIN,答案将跃然纸上。 (很抱歉,我很尖刻,但我个人在 1994 年转向了显式 JOIN,并且再也没有回头。)
SELECT a1.player_id, a1.event_date, SUM(a2.games_played) AS games_so_far
FROM activity a1
JOIN activity a2 ON a1.player_id = a2.player_id
AND a1.event_date >=a2.event_date
GROUP BY a1.player_id, a1.event_date
ORDER BY a1.player_id, a1.event_date
ON 子句第二部分中的
>=
不等式可以解决问题。来自 a1 的每个连续的 event_date
连接到不断增加的行数。然后他们得到总结。
select a.*, sum(a.games_played) over(partition by player_id order by a.event_date rows between unbounded preceding and current row) as games_played
from Activity a;
在 player_id 的窗口上使用窗口函数和滚动求和