2013-01-25 48 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'