2013-08-27 45 views
0

我有一個應用程序可以從幾個(現在是48個)不同的數據點每隔15秒對數據進行一次採樣。這些數據點在表中由兩個不同的外鍵(MeasurementTypeId和GeneratorId),一個樣本值(Value)和一個日期時間(MeasurementDate)表示。如何計算日期時間範圍內的n次平均值?

因此,表看起來是這樣的(我只包括10行,只有少數國外不同的組合鍵)

+------+-------------------+-------------+-------+------------------------+ 
| ID | MeasurementTypeId | GeneratorId | Value | MeasurementDate  | 
+------+-------------------+-------------+-------+------------------------+ 
| 1 |  PSI   |  SG-52 | 0.19 | 2013-08-27 09:19:30 | 
| 2 |  PH   |  SG-52 | 6.39 | 2013-08-27 09:19:30 | 
| 3 |  DEG   |  SG-52 | 90.85 | 2013-08-27 09:19:30 | 
| 4 |  PSI   |  PT-14 | 0.33 | 2013-08-27 09:19:30 | 
| 5 |  PH   |  PT-14 | 6.41 | 2013-08-27 09:19:30 | 
| 6 |  DEG   |  PT-14 | 89.20 | 2013-08-27 09:19:30 | 
| 7 |  PSI   |  SG-52 | 0.20 | 2013-08-27 09:19:45 | 
| 8 |  PH   |  SG-52 | 6.37 | 2013-08-27 09:19:45 | 
| 9 |  DEG   |  SG-52 | 90.84 | 2013-08-27 09:19:45 | 
| 10 |  PSI   |  PT-14 | 0.34 | 2013-08-27 09:19:45 | 
+------+-------------------+-------------+-------+------------------------+ 

我希望創建一個存儲過程,可以返回平均值(按外鍵分組)一段時間範圍內的時間間隔。但是,我不想定義間隔,而是讓用戶調用存儲過程。

我想存儲的過程由numberOfIntervals取參數的

@numberOfIntervals int, 
@startDateRange datetime, 
@endDateRange datetime 

而劃分startDateRange和endDateRange的DATEDIFF以確定的時間間隔在其上做平均。

例如,如果程序被調用,3,「2013年8月26日00:00:00」,「2013年8月27日00:00:00」

結果將是3個記錄每一組由具有值等於平均的間隔8小時的組合(包括爲了簡潔...實際結果只有10個結果將包括18)

+-------------------+-------------+-------+------------------------+ 
| MeasurementTypeId | GeneratorId | Value | MeasurementDate  | 
+-------------------+-------------+-------+------------------------+ 
|  PSI   |  SG-52 | 0.20 | 2013-08-26 08:00:00 | 
|  PH   |  SG-52 | 7.11 | 2013-08-26 08:00:00 | 
|  DEG   |  SG-52 | 90.02 | 2013-08-26 08:00:00 | 
|  PSI   |  PT-14 | 0.44 | 2013-08-26 08:00:00 | 
|  PH   |  PT-14 | 6.98 | 2013-08-26 08:00:00 | 
|  DEG   |  PT-14 | 90.31 | 2013-08-26 08:00:00 | 
|  PSI   |  SG-52 | 0.21 | 2013-08-26 16:00:00 | 
|  PH   |  SG-52 | 7.12 | 2013-08-26 16:00:00 | 
|  DEG   |  SG-52 | 90.01 | 2013-08-26 16:00:00 | 
|  PSI   |  PT-14 | 0.44 | 2013-08-26 16:00:00 | 
+-------------------+-------------+-------+------------------------+ 

我已經做了一些工作來計算移動平均,但這是針對特定的時間範圍和特定數量的時間間隔。有了這個,我希望用戶能夠選擇日期範圍和指定的時間間隔並繪製結果圖。

回答

1

您可以創建一個CTE由

DECLARE @numberOfIntervals INT = 3 
DECLARE @startDateRange DATETIME = '2013-08-27' 
DECLARE @endDateRange DATETIME = '2013-08-28' 

-- 

DECLARE @range INT = DATEDIFF(HH, @startDateRange, @endDateRange)/@numberOfIntervals 

;WITH calendar AS 
(
    SELECT @startDateRange StartDate, DATEADD(HH, @range, @startDateRange) EndDate 
    UNION ALL 
    SELECT DATEADD(HH, @range, StartDate), DATEADD(HH, @range, EndDate) 
    FROM calendar 
    WHERE DATEADD(HH, @range, StartDate) < @endDateRange 
) 

SELECT MeasurementTypeId, 
     GeneratorId, 
     StartDate AS MeasurementDateStart, 
     AVG(Value) AverageValue 
FROM (
    SELECT d.*, c.StartDate 
    FROM data d 
    JOIN calendar c 
     ON d.MeasurementDate >= c.StartDate 
    AND d.MeasurementDate < c.EndDate 
) sub 
GROUP BY MeasurementTypeId, GeneratorId, StartDate 

demo

拿到間隔組,你可能會想補充的是處理@numberOfIntervals沒有很好地劃分一下,加分,而不是小時如果@numberOfIntervals大於24等。

+0

完美。我將其修改爲關閉分鐘(mi),並通過MeasurementTypeId,Gen​​eratorId,StartDate添加了一個命令,以便更清楚地查看結果。在3萬小時的30,000行樣本中,它運行良好。有沒有辦法讓它更有效率?速度將是一個關鍵因素。 – Paul