【问题标题】:Get 30 days prior data for each row of query获取每行查询的 30 天前数据
【发布时间】:2019-05-07 20:07:05
【问题描述】:

我有一个查询,其中有一个包含大约 20k 用户的列表,这些用户在一个月的某个特定周内表示他们已登录到我们的网站。

我需要获得的信息 - 对于这些用户中的每一个,在过去 30 天内,如果他们有 1. 登录:由记录在同一张表中的任何行定义 2. 30 天窗口中的最大事件,在当前 where 子句中的日期之前

这是当前的代码 sn-p,它可以帮助我在给定的一周内将范围缩小到大约 20k 用户:

select
   user_id,
   max(timestamp)
from table 
   where timestamp between '2019-02-01' and '2019-02-05'
group by 1,2;

预期结果集/列:

  1. user_id,
  2. 最大值(时间戳),
  3. logged_on,[如果他们在最大(时间戳)日期之前的 30 天内在同一个表中有任何行数]
  4. previous_timestamp,[最大(时间戳)日期前 30 天内的第二个最近登录日期]

【问题讨论】:

  • 拥有表的架构和一些示例行(包括可以说明答案应该是什么的几行)会有所帮助。我认为,一个困难是显示尚未登录的用户,因为他们没有日期窗口的记录。
  • 是否有一个“最大”日期,或者每个用户有一个最大日期?
  • @BobMcCormick - 谢谢。此表中的其他列都与 URL/流量相关。当用户登录时,user_id 列会填充一个值。如果用户未登录,则该列将为 NULL。我打算过滤掉 NULL 行以仅查看已登录的用户。每个用户没有单一的“最大”日期。我正在将 max 函数应用于由我不会分析和开始的用户周所限制的时间戳。
  • 我认为您需要提供表格中几行的具体示例,其中仅包含感兴趣的列。另外,到目前为止,您尝试过什么查询?
  • 这里是表格的列,括号内有 2 个样本值:1. user_id (A1B2C3; NULL) 2. timestamp (2019-02-01 10:56:35.044; 2019-02- 02 09:50:34.045) 3. url (www.page1.com; www.page2.com) 4. source (facebook; twitter) 使用这个数据集,我目前只过滤一周的数据以获得用户 ID 列表。对于这个用户子集,一周前 30 天的数据(如上所述),希望获得:1. 行数 2. 如果任何这些行的源列包含“facebook”

标签: sql snowflake-cloud-data-platform


【解决方案1】:

我认为这就是您要寻找的。不确定这是否是最有效的方法 - 也许窗口函数可能会执行得更好,但就像 bob-mccormick 提到的那样:棘手的一点是填写用户(分区键)不活动的日期,以便范围查询能够正常工作。

示例数据设置(Snowflake 语法)

-- Create sample table
create temporary table user_logins (userid number, date_logged_on timestamp);
;

-- Insert some random sample data
insert overwrite into user_logins 
select 
    uniform(1,10,random()) userid, 
    dateadd('minutes', uniform(1,86400,random()) * -1,current_timestamp::timestamp_ntz) date_logged_on 
from table(generator(rowcount => 100))
;

选择语句

-- Run select
with user_last_logins as (
  select 
    userid,
    max(date_logged_on) last_login
  from user_logins
  where
    date_logged_on between '2019-01-01' and '2019-05-08'
  group by userid
)
select 
    user_last_logins.userid,
    max(user_last_logins.last_login) last_logged_on,
    count(prior_30_each_user.userid) num_logins_prior_30,
    max(prior_30_each_user.date_logged_on)
from user_last_logins
left join user_logins prior_30_each_user
    on user_last_logins.userid = prior_30_each_user.userid
    and prior_30_each_user.date_logged_on > dateadd('day', -30, user_last_logins.last_login) and prior_30_each_user.date_logged_on < user_last_logins.last_login
group by  user_last_logins.userid
;

【讨论】:

  • 感谢@SimonD - 成功了!感谢这里的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 2020-07-27
  • 2019-11-15
  • 2018-02-19
  • 1970-01-01
相关资源
最近更新 更多