按滑动时间段聚合数据

Data aggregation by sliding time periods

[由于@Gordon Linoff 和@shawnt00 的评论,查询和问题得到了编辑和修复]

我最近继承了一个 SQL 查询,该查询计算日志数据库中 30 天时间 windows 中某些事件的数量。它使用 CTE(通用 Table 表达式)生成从“2019-01-01”到现在的 30 天范围。然后它会计算这 30/60/90 天间隔内的案例。我不确定这是最好的方法。我所知道的是 运行 需要很长时间,而且我 100% 不明白它是如何工作的。所以我正在尝试以一种有效的方式重建它(也许现在是最有效的方式,我不知道)。

我有几个问题:

  1. 我注意到的一件事是,查询没有使用 DATEDIFF,而是简单地从 date.Is 中减去天数,这是一个很好的做法吗?
  2. 有没有更好的时间比较方法?
  3. 有没有更好的方法来完成整个事情?底线是:我需要在 30、60 和 90 天的时间段内按发生次数汇总数据。

注:LogDate原始格式如2019-04-01 18:30:12.000.

DECLARE @dt1 Datetime='2019-01-01'
DECLARE @dt2 Datetime=getDate();

WITH ctedaterange 
     AS (SELECT [Dates]=@dt1 
         UNION ALL
         SELECT [dates] + 30 
         FROM   ctedaterange 
         WHERE  [dates] + 30<= @dt2) 

SELECT 
[dates], 
lt.Activity, COUNT(*) as Total,
    SUM(CASE WHEN lt.LogDate <= dates and lt.LogDate > dates - 90 THEN 1 ELSE 0 END) AS Activity90days,
    SUM(CASE WHEN lt.LogDate <= dates and lt.LogDate > dates - 60 THEN 1 ELSE 0 END) AS Activity60days,
    SUM(CASE WHEN lt.LogDate <= dates and lt.LogDate > dates - 30 THEN 1 ELSE 0 END) AS Activity30days
FROM   ctedaterange AS cte
JOIN (SELECT Activity, CONVERT(DATE, LogDate) as LogDate FROM LogTable) AS lt
ON cte.[dates] = lt.LogDate
group by [dates], lt.Activity
OPTION (maxrecursion 0)

示例数据集 (LogTable):

LogDate, Activity
2020-02-25 01:10:10.000, Activity01
2020-04-14 01:12:10.000, Activity02
2020-08-18 02:03:53.000, Activity02
2019-10-29 12:25:55.000, Activity01
2019-12-24 18:11:11.000, Activity03
2019-04-02 03:33:09.000, Activity01

预期输出(输出未反映上面显示的数据,因为我需要样本集中的太多行才能在此 post 中显示)

正如我上面所说,底线是:我需要在 30、60 和 90 天的时间段内按发生次数汇总数据。

Activity, Activity90days, Activity60days, Activity30days
Activity01, 3, 0, 1
Activity02, 1, 10, 2
Activity03, 5, 1, 3

感谢您的任何建议。

SQL 服务器还没有范围超过 window 分析函数框架的 的选项。由于您已经生成了所有可能的日期并且已经按日期计算了计数,因此很容易回顾特定数量的(聚合的)行以获得正确的总数。这是我建议的 90 天表达方式:

sum(count(LogDate)) over (
    partition by Activity order by [dates]
    with rows between 89 preceding and current row
)