时间序列中的 SQL 滚动计数

Posted

技术标签:

【中文标题】时间序列中的 SQL 滚动计数【英文标题】:SQL Rolling Count in Time Series 【发布时间】:2019-06-20 16:03:07 【问题描述】:

我有一个 SQLite 公司表,以及 10 年来(大约 3000 家公司)每天写多少关于每家公司的新闻文章。我想做一个“滚动”计数,对于每家公司,我计算 3 天窗口内的新闻文章总数,条件是新闻文章的数量为正数。例如,从第 1 天开始,如果文章数为 0,则跳过并转到第 2 天,以此类推,直到我们遇到有 1 篇文章的一天(比如第 4 天),然后计算文章总数接下来 3 天(所以第 4、5、6 天)。之后,我到第 7 天继续扫描,直到找到有新闻文章的第一天,然后重复这 3 天的总和,然后继续扫描,等等。我将为每个公司重复此操作。

我曾考虑使用窗口函数进行滚动求和,但是对于 3000 家公司乘以 365*10 天的数据滚动求和可能在计算上花费的时间太长,而且我不需要在我计算的天数上计算总和跳过(所以要么是 0 天,要么不是 3 天间隔中的第一天)。

例如,每个公司的时间序列可能是(第 # 天:文章数)

Day 1:0
Day 2:0
Day 3:0
Day 4:1
Day 5:3
Day 6:2
Day 7:0
Day 8:0
Day 9:20
Day 10:2
Day 11:0

那么输出将是

Day 4:6 (1 from Day 4, 3 from Day 5, and 2 from Day 6)
Day 9:22 (20 from day 9, 2 from day 10, 0 from day 11).

【问题讨论】:

【参考方案1】:

在较新的 SQLite 版本中,您将使用 row_number()

select company, min(date), max(date), sum(num_articles)
from (select t.*,
             row_number() over (partition by company order by date) as seqnum
      from t
      where num_articles > 0
     ) t
group by company, floor((seqnum - 1) / 3);

【讨论】:

我认为您需要进行一些修改,否则我读错了。我认为您想从子查询中排除 0,并且我认为您正在寻找整数除法而不是 mod,以便将 seqnum 1、2、3 分组为 0,将 4、5、6 分组为 1,依此类推。 @KeithL 。 . .非常感谢。 没问题...我看到了你要去哪里。不需要 2 个答案。 谢谢,这几乎正是我所需要的。根据@KeithL 的建议,我将其更改为 num_articles > 0。剩下的一个问题是,如果在 3 天的范围内有 0,它会跳过 0 并添加随后的非零天,这不完全是我需要。例如,如果按日期计算的计数(从第 1 天开始)为 0,10,0,7,7,1,0,0,1,则代码为第 2 天(10+7+7)和 9 提供 24对于第 6 天 (7+1+1),理想情况下我希望第 2 天 (10+0+7) 为 17,第 5 天 (7+1+0) 为 8,第 9 天为 1?

以上是关于时间序列中的 SQL 滚动计数的主要内容,如果未能解决你的问题,请参考以下文章

SQL 滚动窗口唯一计数

BigQuery:如何执行滚动时间戳窗口组计数,每天产生行

如何在 Oracle SQL 中获得过去三天每天的滚动不同计数?

如何有效地计算熊猫时间序列中的滚动唯一计数?

BigQuery:如何在滚动时间戳窗口内对行进行分组和计数?

SQL Server - 每季度不同客户的运行计数