2012-05-22 73 views
1

我試圖在24小時內有效計算(使用SQL Server 2008)ProductCount的moving average。對於產品表中的每一行,我都想知道過去24小時內ProductCount的平均值(針對特定產品)。我們的數據存在的一個問題是,並非所有日期/時間都存在(請參閱下面的示例)。如果時間戳丟失,這意味着ProductCount爲0.如何計算過去n小時的移動平均數

我有一個包含數百萬行或日期,產品和計數的表格。以下是我必須處理的一個簡單數據示例。

關於如何實現這一點的任何想法?

編輯:我需要的另一個數據是MIN和MAX ProductCount在這段時間(即24小時)。計算最小/最大是有點棘手,因爲缺失值...

+---------------------+-------------+--------------+ 
|   Date  | ProductName | ProductCount | 
+---------------------+-------------+--------------+ 
| 2012-01-01 00:00:00 | Banana | 15000  | 
| 2012-01-01 01:00:00 | Banana | 16000  | 
| 2012-01-01 02:00:00 | Banana | 17000  | 
| 2012-01-01 05:00:00 | Banana | 12000  | 
| 2012-01-01 00:00:00 | Apple |  5000  | 
| 2012-01-01 05:00:00 | Apple |  6000  | 
+---------------------+-------------+--------------+ 

SQL

CREATE TABLE ProductInventory (
    [Date] DATETIME, 
    [ProductName] NVARCHAR(50), 
    [ProductCount] INT 
) 

INSERT INTO ProductInventory VALUES ('2012-01-01 00:00:00', 'Banana', 15000) 
INSERT INTO ProductInventory VALUES ('2012-01-01 01:00:00', 'Banana', 16000) 
INSERT INTO ProductInventory VALUES ('2012-01-01 02:00:00', 'Banana', 17000) 
INSERT INTO ProductInventory VALUES ('2012-01-01 05:00:00', 'Banana', 12000) 
INSERT INTO ProductInventory VALUES ('2012-01-01 00:00:00', 'Apple', 5000) 
INSERT INTO ProductInventory VALUES ('2012-01-01 05:00:00', 'Apple', 6000) 

回答

4

嗯,事實上,你需要計算平均每小時,實際上使這更簡單,因爲您只需要SUM產品數量並將其除以固定數量(24)。所以,我認爲這會得到你想要的結果(儘管在這種特定情況下,光標的是實際上更快):

SELECT A.*, B.ProductCount/24 DailyMovingAverage 
FROM ProductInventory A 
OUTER APPLY ( SELECT SUM(ProductCount) ProductCount 
       FROM ProductInventory 
       WHERE ProductName = A.ProductName 
       AND [Date] BETWEEN DATEADD(HOUR,-23,A.[Date]) AND A.[Date]) B 
+0

哇橘子!這令人印象深刻......我不知道外部適用?我如何在最後24小時添加MIN和MAX?我認爲試圖計算MIN/MAX有點棘手,因爲缺少值。例如,如果有一個缺失值,MIN == 0。 – Martin

3

我加入Lamak的答案,包括最小/最大:

SELECT * 
FROM ProductInventory A 
OUTER APPLY ( 
    SELECT 
     SUM(ProductCount)/24 AS DailyMovingAverage, 
     MAX(ProductCount) AS MaxProductCount, 
     CASE COUNT(*) WHEN 24 THEN MIN(ProductCount) ELSE 0 END AS MinProductCount 
    FROM ProductInventory 
    WHERE ProductName = A.ProductName 
    AND [Date] BETWEEN DATEADD(HOUR, -23, A.[Date]) AND A.[Date]) B 

要解釋缺失的記錄,請檢查在使用MIN(ProductCount)之前最近24小時確實有24條記錄,否則返回0。

工作SQL Fiddle,帶着一幫(每蒲式耳?)加入到顯示MinProductCount工作