2013-01-25 50 views
1

比方说,我在SQL Server 2012中的表UserActivity有两列:月移动平均利用窗口函数

  • ActivityDateTime
  • 用户名

我想在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 
... 
+0

需要近30天呢? –

+0

滑动30天窗口(不仅仅是最近30天) –

回答

0

选项1:对于(同时)循环,虽然每一天,每一个选择落后30天(显然很慢)

选项2:与行每一天的单独的表,并再次对原始表连接(相当慢)。

选项3:递归CTE或存储过程(仍然没有更好)。 (while)与游标组合使用(高效,但需要一些高级SQL知识)。有了这个解决方案,您将按顺序逐步完成每一天和每一行,并跟踪平均值(您将需要某种环绕式数组来了解当一天移出范围时要减去的值)。使用通用/脚本编程语言(C++/Java/PHP)(易于使用这些语言之一的基本知识,高效)的选项3。

Somerelatedquestions

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'