2016-11-29 47 views
1

的數據是如下平均彙總數據:使用SQL Server,我想在給定的時間間隔

Time_Stamp(Datetime)  Value (real) 
---------    ----- 
12:01      1.3 
12:02      1.7 
12:04      2.0 
12:08      1.8 
12:11      1.1 
12:12      2.0 

我希望能夠通過定期平均價值 來概括這個數據。所以,如果我選擇了5分鐘,例如間隔輸出將

Timestamp Value 
--------- ------ 
12:00  1.66 
12:05  1.8 
12:10  1.55 

問候

+0

「Timestamp」列的數據類型是什麼? –

+0

Time_stamp是日期時間 –

+1

您應該考慮使用與時間戳不同的名稱。這意味着什麼是完全不明確的。是創建日期,是否更新?也許這是到期日?當然,時間戳是sql server中的一個數據類型,與一天中的時間無關。 –

回答

2

我經常使用TVF來創建動態的日期/時間範圍。一個理貨表也可以做到這一點。 UDF比遞歸更快,並提供更多功能,即定義日期範圍,DatePart和增量。

Declare @YourTable table (Timestamp time,Value money) 
Insert Into @YourTable values 
('12:01',1.3), 
('12:02',1.7), 
('12:04',2.0), 
('12:08',1.8), 
('12:11',1.1), 
('12:12',2.0) 

Select TimeStamp=R1 
     ,Average=Avg(Value) 
From (Select RetSeq,R1=cast(RetVal as Time),R2=cast(DateAdd(MI,5,RetVal) as Time) from [dbo].[udf-Range-Date]('1900-01-01','1900-01-02','MI',5)) A 
Join @YourTable B on B.TimeStamp>=A.R1 and B.TimeStamp<A.R2 
Group By R1 
Order By R1 

返回

TimeStamp   Average 
12:00:00.0000000 1.6666 
12:05:00.0000000 1.80 
12:10:00.0000000 1.55 

的UDF如果需要

CREATE FUNCTION [dbo].[udf-Range-Date] (@R1 datetime,@R2 datetime,@Part varchar(10),@Incr int) 
Returns Table 
Return (
    with cte0(M) As (Select 1+Case @Part When 'YY' then DateDiff(YY,@R1,@R2)/@Incr When 'QQ' then DateDiff(QQ,@R1,@R2)/@Incr When 'MM' then DateDiff(MM,@R1,@R2)/@Incr When 'WK' then DateDiff(WK,@R1,@R2)/@Incr When 'DD' then DateDiff(DD,@R1,@R2)/@Incr When 'HH' then DateDiff(HH,@R1,@R2)/@Incr When 'MI' then DateDiff(MI,@R1,@R2)/@Incr When 'SS' then DateDiff(SS,@R1,@R2)/@Incr End), 
     cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)), 
     cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a, cte1 b, cte1 c, cte1 d, cte1 e, cte1 f, cte1 g, cte1 h), 
     cte3(N,D) As (Select 0,@R1 Union All Select N,Case @Part When 'YY' then DateAdd(YY, N*@Incr, @R1) When 'QQ' then DateAdd(QQ, N*@Incr, @R1) When 'MM' then DateAdd(MM, N*@Incr, @R1) When 'WK' then DateAdd(WK, N*@Incr, @R1) When 'DD' then DateAdd(DD, N*@Incr, @R1) When 'HH' then DateAdd(HH, N*@Incr, @R1) When 'MI' then DateAdd(MI, N*@Incr, @R1) When 'SS' then DateAdd(SS, N*@Incr, @R1) End From cte2) 

    Select RetSeq = N+1 
      ,RetVal = D 
    From cte3,cte0 
    Where D<[email protected] 
) 
/* 
Max 100 million observations -- Date Parts YY QQ MM WK DD HH MI SS 
Syntax: 
Select * from [dbo].[udf-Range-Date]('2016-10-01','2020-10-01','YY',1) 
Select * from [dbo].[udf-Range-Date]('2016-01-01','2017-01-01','MM',1) 
+0

謝謝@John Cappelleti您的答案現場我會明確地使用它後,輕微的調整。 –

1
SELECT Timestamp, 
     AVG(VALUE) AS Value 
    FROM 
    (
     SELECT CASE WHEN Timestamp BETWEEN 12:00 AND 12:05 THEN 12:00 
        WHEN Timestamp BETWEEN 12:05 AND 12:10 THEN 12:05 
        WHEN Timestamp BETWEEN 12:10 AND 12:15 THEN 12:10 
       END AS Timestamp, 
       VALUE 
      FROM data 
    ) 
GROUP BY Timestamp; 
+1

此解決方案特定於這個例子中的數據集並不會對試圖實現這一點的任何人有用。 –

+0

謝謝@Teja我很欣賞你的意見。 –

1

一種方法是創建一個time table。您可以將所需的任何字段添加到此表格中,從而爲您提供分組。

此示例使用recursion返回一個簡單的時間表,用於說明目的。在你的數據庫中,我建議創建一個合適的表。

-- Sample time table. 
WITH DimTime AS 
    (
     -- Returns one record for each minute of the day. 
      SELECT 
       CAST('00:00:00' AS TIME(0)) AS TimeKey, 
       0       AS [Hour], 
       1       AS AM 

     UNION ALL 

      SELECT 
       c.NextMinute             AS TimeKey, 
       DATEPART(HOUR, c.NextMinute)         AS [Hour], 
       CASE WHEN DATEPART(HOUR, c.NextMinute) < 12 THEN 1 ELSE 0 END AS AM 

      FROM 
       DimTime AS t 
        CROSS APPLY 
         (
          VALUES 
           (DATEADD(MINUTE, 1, TimeKey)) 
         ) AS c(NextMinute) 
      WHERE 
       t.TimeKey < CAST('23:59:00' AS TIME(0)) 
    ) 
SELECT 
    * 
FROM 
    DimTime 
OPTION 
    (MAXRECURSION 1440) 
; 

返回

TimeKey  Hour AM 
00:00:00 0  1 
00:01:00 0  1 
... 
11:59:00 11  1 
12:00:00 12  0 
... 
23:59:00 23  0 

將一列呼籲沿FiveMinuteInterval東西線將簡化您的最終查詢。

相關問題