如何使用窗口函数获取每个日期值的今天、过去 7 天、过去 30 天的指标?

Posted

技术标签:

【中文标题】如何使用窗口函数获取每个日期值的今天、过去 7 天、过去 30 天的指标?【英文标题】:How to use window functions to get meterics for today, last 7 days, last 30 days for each value of the date? 【发布时间】:2016-01-06 23:33:39 【问题描述】:

我的问题在纸面上看起来很简单:

对于给定日期,给我该给定日期的活跃用户,给定_Date()-7 中的活跃用户,给定_Date()-30 中的活跃用户

即样本数据。

"timestamp" "user_public_id"
"23-Sep-15" "805a47023fa611e58ebb22000b680490"
"28-Sep-15" "d842b5bc5b1711e5a84322000b680490"
"01-Oct-15" "ac6b5f70b95911e0ac5312313d06dad5"
"21-Oct-15" "8c3e91e2749f11e296bb12313d086540"
"29-Nov-15" "b144298810ee11e4a3091231390eb251"

对于 01-10,今天的计数为 1,last_7_days 为 3,last_30_days 为 3+n(其中 n 是 30 天窗口中 10 月 1 日之前日期的 user_ids 计数)

我在亚马逊红移。有人可以提供一个示例 sql 来帮助我入门吗? 输出应如下所示:

"timestamp" "users_today", "users_last_7_days", "users_30_days"
"01-Oct-15"           1                 3           (3+n)

【问题讨论】:

我认为你不需要窗口函数,这很简单。 我认为你应该看看你在哪个网站,不要发布没有任何贡献的cmets。 抱歉,我无法可靠地输入比我的智能手机更多的内容。我会尽快从我的笔记本电脑上添加答案... 【参考方案1】:

我知道寻求帮助/不完整的解决方案是不受欢迎的,但这并没有引起任何其他关注,所以我想我会尽我所能。

我一直在拔头发,试图把这个弄出来,唉,我是一个初学者,有些东西不适合我。也许你自己或其他人能够大幅改进我的答案,但我认为我走在正确的轨道上。

SELECT replace(convert(varchar, [timestamp], 111), '/','-') AS [timestamp], -- to get date in same format as you require
(SELECT COUNT([TIMESTAMP]) FROM #SIMPLE WHERE ([TIMESTAMP]) = ([timestamp])) AS users_today,
(SELECT COUNT([TIMESTAMP]) FROM #SIMPLE WHERE [TIMESTAMP] BETWEEN DATEADD(DY,-7,[TIMESTAMP]) AND [TIMESTAMP]) AS users_last_7_days ,
(SELECT COUNT([TIMESTAMP]) FROM #SIMPLE WHERE [TIMESTAMP] BETWEEN DATEADD(DY,-30,[TIMESTAMP]) AND [timestamp]) AS users_last_30_days
FROM #SIMPLE
GROUP BY [timestamp]

从这里开始:

CREATE TABLE #SIMPLE (
[timestamp] datetime, user_public_id varchar(32)
)

INSERT INTO #SIMPLE 
VALUES('23-Sep-15','805a47023fa611e58ebb22000b680490'),
('28-Sep-15','d842b5bc5b1711e5a84322000b680490'),
('01-Oct-15','ac6b5f70b95911e0ac5312313d06dad5'),
('21-Oct-15','8c3e91e2749f11e296bb12313d086540'),
('29-Nov-15','b144298810ee11e4a3091231390eb251')

我遇到的问题是,尽管我按 [timestamp] 分组,但每一行都包含相同的计数。

【讨论】:

感谢您的尝试,但我不认识那种 SQL 风格。我已经在下面发布了解决方案。 @smooth_smoothie 这是非常标准的 SQL,除了 # 表示临时表,这是一个 SQL Server 习惯用法。如果您需要特定风格的 SQL,您应该在问题或标签中指出。还有DATEADD,但日期算术是跨实现非常不标准的事情之一。 嗯,我刚刚检查了一下,DATEADD 似乎是 Redshift 的有效 SQL。【参考方案2】:

第 1 步——创建一个包含每日计数的表格。

create temp table daily_mobile_Sessions as
select "timestamp" ,
count(user_public_id) over (partition by  "timestamp"  ) as "today"
from mobile_sessions 
group by 1, mobile_sessions.user_public_id
order by 1 DESC

第 2 步 -- 根据上表。我们创建了另一个可以使用“today”字段的表,并应用窗口函数对计数求和。

select "timestamp", today,
sum(today) over (order by "timestamp" rows between 6 PRECEDING and CURRENT ROW) as "last_7days",
sum(today) over (order by "timestamp" rows between 29 PRECEDING and CURRENT ROW) as "last_30days"
 from daily_mobile_Sessions group by "timestamp"  , 2 order by 1 desc

【讨论】:

第 2 步仅在每天恰好有一行时才有效。或多或少,任何偏差都不起作用(例如,您的样本数据不符合此要求)。只要您确定这是真的,那么没问题,但如果不是,那么您将需要一种不同的方法。

以上是关于如何使用窗口函数获取每个日期值的今天、过去 7 天、过去 30 天的指标?的主要内容,如果未能解决你的问题,请参考以下文章

如何用Python在指定日期上减去7天?

如何使用Parse JS SDK查询过去7天的对象?

Spark 窗口函数 - rangeBetween 日期

使用 INTL 从今天开始获取整周的天数

如何将行旋转为列,并按过去 7 天显示 - SQL SERVER

如何从今天开始从 DB2 获取过去 7 天(1 周)的记录