Reputation: 2315
I have the following table
timestamp parameter value
---------------------------------------------------
2015-09-04 10:00:00.000 par01 1
2015-09-04 10:03:00.000 par02 2
2015-09-04 10:06:00.000 par03 3
2015-09-04 10:09:00.000 par04 4
2015-09-04 10:12:00.000 par05 5
2015-09-04 10:15:00.000 par06 6
2015-09-04 10:18:00.000 par01 7
2015-09-04 10:21:00.000 par02 8
2015-09-04 10:24:00.000 par03 9
2015-09-04 10:27:00.000 par04 10
I would like to calculate the weighted average every 15 minutes. The result must be like this:
timestamp parameter value
---------------------------------------------------
2015-09-04 10:00:00.000 result1 3
2015-09-04 10:15:00.000 result2 8
What's the fastest way? Is It possible avoiding loops?
Upvotes: 1
Views: 1022
Reputation: 44326
This will give you the result you are requesting:
DECLARE @t table(timestamp datetime, parameter char(5), value int)
INSERT @t values
('2015-09-04 10:00:00.000','par01',1),
('2015-09-04 10:03:00.000','par02',2),
('2015-09-04 10:06:00.000','par03',3),
('2015-09-04 10:09:00.000','par04',4),
('2015-09-04 10:12:00.000','par05',5),
('2015-09-04 10:15:00.000','par06',6),
('2015-09-04 10:18:00.000','par01',7),
('2015-09-04 10:21:00.000','par02',8),
('2015-09-04 10:24:00.000','par03',9),
('2015-09-04 10:27:00.000','par04',10)
SELECT
dateadd(minute, datediff(minute, 0,timestamp)/15*15, 0) timestamp,
'Result' + cast(row_number() over (order by datediff(minute, 0,timestamp)/15)
as varchar(10)) parameter,
avg(value) value
FROM @t
GROUP BY datediff(minute, 0,timestamp)/15
Result:
timestamp parameter value
2015-09-04 10:00 Result1 3
2015-09-04 10:15 Result2 8
EDIT here is a method to calculated weighted average. Been a learning experience for me:
;WITH CTE as
(
SELECT
cast(coalesce(lead(timestamp) over (order by timestamp),
dateadd(minute, datediff(minute, 0,timestamp)/15*15, '00:15'))
- timestamp as float)*24*60/15*value x,
dateadd(minute, datediff(minute, 0,timestamp)/15*15, 0) truncatedtime
FROM @t
)
SELECT
sum(x) weighted_average,
truncatedtime
FROM
cte
GROUP BY
truncatedtime
Upvotes: 2
Reputation: 82474
try this:
SELECT MIN(timestamp) as timestamp,
'result' + cast(count(*) over(order by min(timestamp)) as varchar(10)) as parameter,
AVG(value) as value
FROM tbl
GROUP BY CAST(timestamp as Date),
DATEPART(Hour, timestamp),
DATEPART(Minute, timestamp) / 15
Upvotes: 2
Reputation: 7753
Try this:
CREATE TABLE #t1
(
[Timestamp] datetime,
Parameter VARCHAR(50),
Value int
)
INSERT INTO #t1
VALUES ('2015-09-04 10:00:00.000', 'par01',1),
('2015-09-04 10:03:00.000', 'par02',2),
('2015-09-04 10:06:00.000', 'par03',3),
('2015-09-04 10:09:00.000', 'par04',4),
('2015-09-04 10:12:00.000', 'par05',5),
('2015-09-04 10:15:00.000', 'par06',6),
('2015-09-04 10:18:00.000', 'par01',7),
('2015-09-04 10:21:00.000', 'par02',8),
('2015-09-04 10:24:00.000', 'par03',9),
('2015-09-04 10:27:00.000', 'par04',10)
;WITH CTE
As
(
SELECT
DATEADD( minute,
( DATEDIFF(minute, CONVERT(char(8),[Timestamp],112), [Timestamp]) / 15 ) * 15,
CONVERT(char(8),[Timestamp],112) ) as Timestamp_truncated,
[Timestamp],
parameter,
value
FROM #t1
)
SELECT Timestamp_truncated AS [Timestamp], AVG(Value) as Value
FROM CTE
GROUP BY Timestamp_truncated
Upvotes: 2