使用窗口函数的SQL Server中用户活动的月移动平均值

时间:2013-01-25 07:51:12

标签: sql sql-server-2012

假设我在SQL Server 2012中有一个表UserActivity,有两列:

  • ActivityDateTime
  • 用户ID

我想每天计算30天内任何活动的不同用户数(我的每月活跃用户数)。 (所以我有一个30天的窗口,一次增加一天。如何有效地使用SQL Server中的窗口函数?

输出如下:

Date,NumberActiveUsersInPrevious30Days
01-01-2010,13567
01-02-2010,14780
01-03-2010,13490
01-04-2010,15231
01-05-2010,15321
01-06-2010,14513
...

2 个答案:

答案 0 :(得分:1)

SQL Server不支持COUNT(DISTINCT ... ) OVER ()或数字值30 PRECEDING)与RANGE

一起使用

我不打算强迫窗口函数执行此操作。由于COUNT(DISTINCT UserID)的要求,它总是需要重新检查每个日期的整个30天窗口。

您可以为每个日期创建一个包含行的日历表,然后使用

SELECT C.Date,
       NumberActiveUsersInPrevious30Days
FROM   Calendar C
       CROSS APPLY (SELECT COUNT(DISTINCT UserID)
                   FROM   UserActivity
                   WHERE  ActivityDateTime >= DATEADD(DAY, -30, C.[Date])
                   AND ActivityDateTime < C.[Date]) CA(NumberActiveUsersInPrevious30Days)
WHERE  C.Date BETWEEN '2010-01-01' AND '2010-01-06' 

答案 1 :(得分:0)

选项1:每天循环播放(while)并为每个循环选择30天(显然非常慢)。

选项2:一个单独的表格,每天都有一行,并加入原始表格(再次非常慢)。

选项3:递归CTE或存储过程(仍然没有做得更好)。

选项4:对于(while)循环与游标组合(高效,但需要一些高级SQL知识)。使用此解决方案,您将按顺序逐步浏览每一天和每一行并跟踪平均值(您需要某种环绕式数组来了解当一天超出范围时要减去的值)。

选项5:通用/脚本编程语言(C ++ / Java / PHP)中的选项3(易于使用其中一种语言的基本知识,高效)。

Some related questions