使用 SQL 获取表中每个用户最近 n 天的活动 [关闭]

Posted

技术标签:

【中文标题】使用 SQL 获取表中每个用户最近 n 天的活动 [关闭]【英文标题】:Using SQL to get recent n days activity of every user in the table [closed] 【发布时间】:2020-10-07 18:30:26 【问题描述】:

我有一张用户游戏活动表,类似于

因此,为简单起见,只需考虑 account_id 和 date 列。到现在为止,您可能已经理解每条记录代表一个玩家在特定的一天玩某个游戏。我要提取的是每个用户从上一场比赛开始倒数最近 15 天的活动。例如,我们的数据范围从 2020 年 4 月 4 日到 2020 年 9 月 24 日,假设用户在 2020 年 9 月 20 日玩了他的最后一场游戏,并且从那以后没有玩任何游戏,所以对于那个用户,我想要他的游戏活动日期从 9 月 5 日到 20 日(距离他上一场比赛的前 15 天),我想为每个用户提取相同的数据。

我最初想像这样实现......根据日期按降序对表格进行排序,并在 account_id 第一次出现时将日期与该特定帐户匹配(以创建一个字典,其中的键是 account_id 并且 value 是他玩的最后日期),这样我就可以从 value 中减去 15 天并过滤每个 account_id 的数据,但我的同事对此并不满意,并希望一次完成所有这些(使用 SQL 查询)。有人可以指导我如何做到这一点。在此先感谢:)

【问题讨论】:

见meta.***.com/questions/333952/… 【参考方案1】:

如果我理解正确,您基本上是在寻找 MAX(Date) Grouped BY User 作为您的起点(实际上是终点)。

将它放在子查询或 CTE 中是最简单的。

然后您可以简单地使用用户的最后日期作为结束日期再次查询您的表,并计算该日期 - 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 天的时间,而不管实际日期如何,我个人会使用窗口函数来倒数 我将其拆分为 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 Server 上试过这个,但 mysql 应该也能正常工作

【讨论】:

@Strawberry ....感谢您的努力....它工作正常。是否可以获得每个用户最近 15 天的活跃天数,即假设用户在 2020 年 9 月 16 日、17 日、18 日、19 日、23 日、26 日玩了一些游戏,而今天的日期是 2020 年 10 月 8 日。方法我们将只获得属于 2020 年 9 月 26 日的条目(从 10 月 8 日开始的 15 天是 2020 年 9 月 24 日)。但我想要的是从他最近玩的日期算起的天数到 15 天,他只在他活跃的日期玩(即玩了一些游戏) @DroningHangman 不要感谢我。感谢 ALICE-down-the-ZOMBIE-hole! 好的.....谢谢@AlLICE,你能指导我进行下一步吗【参考方案2】:

如果您运行的是 MySQL 8.0,您可以使用窗口函数来执行此操作:

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

【讨论】:

以上是关于使用 SQL 获取表中每个用户最近 n 天的活动 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

查询用户出现在表中后的前 48 小时活动 (HiveQL / SQL)

Sql Server 只允许每个用户使用一个活动图像

LeetCode:Database 57.过去30天的用户活动 II

SQL 为每个组选择最近的记录

在sql中获取从当前日期起最近90天的记录

参考日期前后的 sql 持续时间