使用 SQL 获取 table 中每个用户的最近 n 天 activity
Using SQL to get recent n days activity of every user in the table
我有一个 table 游戏 activity 的用户看起来像这样
因此,为简单起见,只需考虑 account_id 和日期列。到目前为止,您可能已经了解每条记录代表一位玩家在特定日期玩某款游戏。我想提取的是最近 15 天 activity 每个用户从他上次玩的游戏开始倒数。例如,我们的数据范围是从 2020 年 4 月 4 日到 2020 年 9 月 24 日,假设一个用户在 2020 年 9 月 20 日玩了他的最后一场游戏并且从那以后就没有玩过任何游戏,所以对于那个用户我希望他玩 activity 的日期范围是 9 月 5 日到 20 日(从他上次玩游戏的前 15 天),我想为每个用户提取相同的数据。
我最初想这样实现......根据日期对 table 进行降序排序,并在 account_id 出现时将日期与该特定帐户匹配第一次(创建一个字典,其中键是 account_id,值是他最后一次玩的日期)这样我就可以从值中减去 15 天并过滤每个 account_id 的数据,但是我的同事worker 对此并不满意,并希望一次完成所有这些(使用 SQL 查询)。有人可以指导我如何做到这一点。提前致谢:)
如果我理解正确的话,您基本上是在寻找 MAX(Date) Grouped BY User 作为您的起点(实际上是终点)。
将它放在子查询或 CTE 中是最简单的。
然后您可以简单地再次查询您的 table,使用用户的最后日期作为您的结束日期,并计算该日期 - 15 天作为您的起点。
这将检索给定时间段内用户的所有条目。
示例:
WITH BASE AS(
SELECT
MAX(Date) AS LastDate,
UserID
FROM GameActivity
GROUP BY UserID
)
SELECT
ga.UserID,
ga.Date
FROM GameActivity GA
JOIN BASE B ON b.UserID = ga.UserID
WHERE ga.Date >= DATE_SUB(b.LastDate, INTERVAL 15 DAY)
AND ga.Date <= b.LastDate
编辑:
为了得到过去 15 天而不考虑实际日期,我个人会使用 Window 函数来倒数
我将其分成 2 个 CTE 以突出逻辑
WITH DistinctDates AS (
SELECT DISTINCT
user_id,
active_date
FROM userdata
),
DAYCount AS (
SELECT
user_id,
active_date,
COUNT(active_date) OVER (PARTITION BY user_id ORDER BY active_date DESC) AS ActiveDays
FROM DistinctDates
)
SELECT
dc.user_id,
ud.active_date,
dc.ActiveDays
FROM DayCount DC
JOIN userdata UD ON ud.user_id = dc.user_id AND ud.active_date = dc.active_date
WHERE ActiveDays BETWEEN 1 AND 15
ORDER BY dc.user_id, dc.ActiveDays ;
我在 MS SQL 服务器上尝试过,但 MySQL 应该可以正常工作
如果你是 运行 MySQL 8.0,你可以使用 window 函数来做到这一点:
select *
from (
select t.*, max(date) over(partition by account_id) max_date
from mytable t
) t
where date >= max_date - interval 15 day
在早期版本中,替代方法是相关子查询:
select *
from mytable t
where date >= (select max(t1.date) from mytable t1 where t1.account_id = t.account_id) - interval 15 day
或使用连接:
select *
from mytable t
inner join (select account_id, max(date) max_date from mytable group by account_id) m
on t.date >= m.max_date - interval 15 day
我有一个 table 游戏 activity 的用户看起来像这样
因此,为简单起见,只需考虑 account_id 和日期列。到目前为止,您可能已经了解每条记录代表一位玩家在特定日期玩某款游戏。我想提取的是最近 15 天 activity 每个用户从他上次玩的游戏开始倒数。例如,我们的数据范围是从 2020 年 4 月 4 日到 2020 年 9 月 24 日,假设一个用户在 2020 年 9 月 20 日玩了他的最后一场游戏并且从那以后就没有玩过任何游戏,所以对于那个用户我希望他玩 activity 的日期范围是 9 月 5 日到 20 日(从他上次玩游戏的前 15 天),我想为每个用户提取相同的数据。
我最初想这样实现......根据日期对 table 进行降序排序,并在 account_id 出现时将日期与该特定帐户匹配第一次(创建一个字典,其中键是 account_id,值是他最后一次玩的日期)这样我就可以从值中减去 15 天并过滤每个 account_id 的数据,但是我的同事worker 对此并不满意,并希望一次完成所有这些(使用 SQL 查询)。有人可以指导我如何做到这一点。提前致谢:)
如果我理解正确的话,您基本上是在寻找 MAX(Date) Grouped BY User 作为您的起点(实际上是终点)。
将它放在子查询或 CTE 中是最简单的。
然后您可以简单地再次查询您的 table,使用用户的最后日期作为您的结束日期,并计算该日期 - 15 天作为您的起点。
这将检索给定时间段内用户的所有条目。
示例:
WITH BASE AS(
SELECT
MAX(Date) AS LastDate,
UserID
FROM GameActivity
GROUP BY UserID
)
SELECT
ga.UserID,
ga.Date
FROM GameActivity GA
JOIN BASE B ON b.UserID = ga.UserID
WHERE ga.Date >= DATE_SUB(b.LastDate, INTERVAL 15 DAY)
AND ga.Date <= b.LastDate
编辑:
为了得到过去 15 天而不考虑实际日期,我个人会使用 Window 函数来倒数 我将其分成 2 个 CTE 以突出逻辑
WITH DistinctDates AS (
SELECT DISTINCT
user_id,
active_date
FROM userdata
),
DAYCount AS (
SELECT
user_id,
active_date,
COUNT(active_date) OVER (PARTITION BY user_id ORDER BY active_date DESC) AS ActiveDays
FROM DistinctDates
)
SELECT
dc.user_id,
ud.active_date,
dc.ActiveDays
FROM DayCount DC
JOIN userdata UD ON ud.user_id = dc.user_id AND ud.active_date = dc.active_date
WHERE ActiveDays BETWEEN 1 AND 15
ORDER BY dc.user_id, dc.ActiveDays ;
我在 MS SQL 服务器上尝试过,但 MySQL 应该可以正常工作
如果你是 运行 MySQL 8.0,你可以使用 window 函数来做到这一点:
select *
from (
select t.*, max(date) over(partition by account_id) max_date
from mytable t
) t
where date >= max_date - interval 15 day
在早期版本中,替代方法是相关子查询:
select *
from mytable t
where date >= (select max(t1.date) from mytable t1 where t1.account_id = t.account_id) - interval 15 day
或使用连接:
select *
from mytable t
inner join (select account_id, max(date) max_date from mytable group by account_id) m
on t.date >= m.max_date - interval 15 day