【问题标题】:Extracting data of recent n active days of every user from dataframe of gaming activity从游戏活动数据框中提取每个用户最近n个活跃日的数据
【发布时间】:2021-01-23 13:05:26
【问题描述】:

所以,首先,数据看起来像这样:

Sample Data if you would like to work

表中的每条记录都代表一个特定的用户,他们用一定数量的钱玩特定类型的游戏。因此,用户可能有一天会玩而不是其他天。

我想提取的是......用户在他们最后活跃的 n 天中的活动(假设 n 是 15)。为了清楚起见,我举个例子:假设一个 account_id 为 12345 的用户在 2020 年 9 月 16、17、18、19、25、26 和 2020 年 10 月 8 日玩了一些游戏(他玩的游戏没有没关系,那些日子他至少打了一场比赛)。到目前为止,我所做的是从他最近玩的日期(2020 年 10 月 8 日到 15 天前,即 2020 年 9 月 24 日)中提取了该玩家的活动。所以,我只会有玩家在 2020 年 9 月 25,26 日和 2020 年 10 月 8 日的游戏活动。但我想要的是过去 15 天的活动,包括 2020 年 10 月 8 日和 9 月 16,17,18 ,19,25,26 和之前的 8 个活动天(因为我想要 15 天,我提到的日期数为 7)

我对过去 15 天活动的处理方式(我可能是活跃的或不活跃的)是

WITH BASE AS( 
SELECT 
MAX(date) AS LastDate, 
account_id 
FROM aug 
GROUP BY account_id
) 
SELECT 
ga.account_id, 
ga.date
FROM aug GA 
JOIN BASE B ON b.account_id = ga.account_id 
WHERE ga.date >= DATE_SUB(b.LastDate, INTERVAL 15 DAY) 
  AND ga.date <= b.LastDate  

我无法将过去 15 天转换为最后活跃的 15 天。请指导我。 提前致谢:)

【问题讨论】:

  • @forpas 没关系。

标签: sql sqlite datetime window-functions pandasql


【解决方案1】:

不需要连接。
您在表 aug 中拥有您需要的所有数据。
使用DENSE_RANK()窗口函数选择最近15个活跃天的行:

select account_id, date, Real_money, table_name
from (
  select *, dense_rank() over (order by date desc) dr
  from aug 
  where account_id = ?
) t
where dr <= 15 

? 替换为您要搜索的account_id

如果您想要所有account_ids 的结果:

select account_id, date, Real_money, table_name
from (
  select *, dense_rank() over (partition by account_id order by date desc) dr
  from aug 
) t
where dr <= 15 

对于 3.25.0 之前的 SQLite 版本,没有窗口函数,创建这个索引:

CREATE INDEX aug_account_id_date ON aug(account_id, date);

并尝试:

select a.* from aug a
where a.date >= coalesce(
  (
    select distinct date 
    from aug
    where account_id = a.account_id
    order by date desc limit 14, 1
  ), '0000-00-00'
)

或:

select a.* from aug a
where (select count(distinct date) from aug where account_id = a.account_id and date >= a.date) <= 15

请参阅demo

【讨论】:

  • 嗨@forpas...对于数据中存在的所有唯一account_id,我需要相同的东西
  • @Forpas....它说语法错误...不知道为什么 (PandaSQLException: (sqlite3.OperationalError) 靠近 "(": 语法错误 [SQL: select account_id, date, Real_money, table_name from (select *, dense_rank() over (partition by account_id order by date desc) dr from aug) t where dr
  • @DroningHangman 如果您使用的是 SQLite,为什么要标记 MySql?无论如何,代码在 SQLite 中也可以正常工作:dbfiddle.uk/…
  • @Forpass,很抱歉,戈登回答后,我已将标签更改为 pandasql。我理解您编写的查询,但不知道为什么会出现语法错误。请让我知道你是否能弄清楚:test_q = psql.sqldf("select account_id, date, Real_money, table_name from (select *, dense_rank() over (partition by account_id order by date desc) dr from aug) where dr
  • SQLite 中的窗口函数从 3.25.0 版本开始支持,这就是你得到语法错误的原因。我将发布一个没有窗口函数的新查询,但如果您的表与 csv 一样大,它的效率会低得多。
【解决方案2】:

如果我理解正确:

SELECT gab.*
FROM (SELECT ga.account_id, ga.date,
             DENSE_RANK() OVER (ORDER BY b.LastDate DESC) as seqnum
      FROM aug GA JOIN
           BASE b
           ON b.account_id = ga.account_id 
     ) gab
WHERE seqnum >= 15;

【讨论】:

  • 嗨@Gordon,感谢您的努力。你能解释一下这是如何工作的,而且这也将在 sqlite3 中工作。基本上我在 jupyter notebook 中工作,我正在使用 pandasql 库,当我这样做时出现语法错误 :: test = psql.sqldf("WITH BASE AS( SELECT MAX(date) AS LastDate, account_id FROM aug GROUP BY account_id) SELECT gab.* FROM (SELECT aug.account_id, aug.date, DENSE_RANK() OVER (ORDER BY b.LastDate DESC) as seqnum FROM aug GA JOIN BASE b ON b.account_id = ga.account_id) gab WHERE seqnum >= 15 ")
  • @DroningHangman 为您的问题设置正确的标签。这是 SQLite 还是 MySql?您的代码适用于 MySql。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
  • 2022-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-14
  • 1970-01-01
相关资源
最近更新 更多