Mysql 使用SQL获取表中每个用户最近n天的活动

Mysql 使用SQL获取表中每个用户最近n天的活动,mysql,sql,datetime,max,window-functions,Mysql,Sql,Datetime,Max,Window Functions,我有一张用户的游戏活动表,看起来像这样 所以,为了简单起见,只考虑Actudio ID和Dead列。到现在为止,你可能已经明白了,每一张唱片都代表着一个玩家在某一天玩某个游戏。我想提取的是每个用户最近15天的活动,从上次玩的游戏开始倒数。例如,我们有从2020年4月4日到2020年9月24日的数据,假设一个用户在2020年9月20日玩了他的最后一个游戏,从那时起就再也没有玩过任何游戏,因此对于该用户,我希望他的玩游戏活动在9月5日到20日之间(从上次玩游戏的15天之前)我想为每个用户提取相同的数

我有一张用户的游戏活动表,看起来像这样

<>所以,为了简单起见,只考虑Actudio ID和Dead列。到现在为止,你可能已经明白了,每一张唱片都代表着一个玩家在某一天玩某个游戏。我想提取的是每个用户最近15天的活动,从上次玩的游戏开始倒数。例如,我们有从2020年4月4日到2020年9月24日的数据,假设一个用户在2020年9月20日玩了他的最后一个游戏,从那时起就再也没有玩过任何游戏,因此对于该用户,我希望他的玩游戏活动在9月5日到20日之间(从上次玩游戏的15天之前)我想为每个用户提取相同的数据


我最初的想法是这样实现。。。。。根据日期按降序对表格进行排序,并将该帐户id首次出现时的日期与该特定帐户相匹配(创建一个字典,其中键为帐户id,值为他上次播放的日期),以便我可以从值中减去15天,并过滤每个帐户id的数据,但我的同事对此并不满意,他希望在一次机会内完成这一切(使用SQL查询)。有人能指导我怎么做吗。提前感谢:)

如果我理解正确,您基本上是在寻找按用户分组的最大(日期)作为起点(实际终点)

最容易将其放入子查询或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  

我在MS SQL Server上尝试了这一点,但MySQL应该也能起到同样的作用

如果我理解正确,您基本上是在寻找按用户分组的最大(日期)作为起点(实际上是终点)

最容易将其放入子查询或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  

我在MS SQL Server上尝试了这一点,但MySQL应该也能工作

如果您运行的是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

如果您运行的是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

请看@草莓……谢谢你的努力……它工作得很好。是否有可能为每个用户获得最近15个活动日,即假设一个用户在2020年9月16、17、18、19、23、26日玩了一些游戏,今天的日期是2020年10月8日。如果我们使用之前的方法,我们只会得到属于2020年9月26日的条目(从10月8日起15天是2020年9月24日)。但我想要的是,从他最近的比赛日期算起,从15天算起,他只在他活跃的日期(即玩了一些游戏)才开始比赛。谢谢爱丽丝,从僵尸洞下去!好的……谢谢@AlLICE,你能指导我下一步吗want@Strawberry…谢谢你的努力…很好用。是否有可能为每个用户获得最近15个活动日,即假设一个用户在2020年9月16、17、18、19、23、26日玩了一些游戏,今天的日期是2020年10月8日。如果我们使用之前的方法,我们只会得到属于2020年9月26日的条目(从10月8日起15天是2020年9月24日)。但我想要的是,从他最近的比赛日期算起,从15天算起,他只在他活跃的日期(即玩了一些游戏)才开始比赛。谢谢爱丽丝,从僵尸洞下去!好的……谢谢@AlLICE,你能指导我下一步要做什么吗