I am trying to write a SQL call that will time weight average data in any desired interval. This meaning i only have to change a few parameters inside the query so the final output will be in Day's, Hours and or minutes between my two desired dates.
I also need it to fill in data between missing intervals like this Example
Actual DataBase Data
Time_Stamp Time_Stamp_ms BPS_FIT0161
2014-07-26 22:32:36 74 164
2014-07-26 22:32:37 71 164
2014-07-26 22:32:38 71 164
2014-07-26 22:32:39 70 162
2014-07-26 22:32:40 71 162
2014-07-26 22:32:41 67 162
2014-07-26 22:32:42 64 165
2014-07-26 22:32:43 63 164
2014-07-26 22:32:44 62 164
2014-07-26 22:32:45 63 163
2014-07-26 22:32:46 59 163
2014-07-26 22:32:47 56 165
2014-07-26 22:32:48 55 167
2014-07-26 22:32:49 54 167
2014-07-26 22:32:50 54 168
2014-07-26 22:32:51 51 168
2014-07-26 22:32:52 47 171
2014-07-26 22:32:53 46 173
2014-07-26 22:32:54 111 177
2014-07-26 22:32:55 42 178
2014-07-26 22:38:56 99 178
2014-07-26 23:24:57 426 178
2014-07-27 00:21:58 854 178
2014-07-27 01:53:09 229 178
2014-07-27 03:30:11 419 178
2014-07-27 05:25:14 56 178
2014-07-27 07:32:16 881 178
2014-07-27 09:48:20 48 178
2014-07-27 12:55:24 286 178
2014-07-27 16:13:28 562 178
2014-07-27 20:10:33 803 178
2014-07-28 00:56:40 26 178
2014-07-28 06:38:47 753 178
2014-07-28 08:38:47 753 178
2014-07-28 09:24:37 219 248
2014-07-28 09:24:38 218 248
2014-07-28 09:24:39 214 226
2014-07-28 09:24:40 212 226
2014-07-28 09:24:41 212 226
2014-07-28 09:24:42 208 224
2014-07-28 09:24:43 207 222
2014-07-28 09:24:44 206 222
2014-07-28 09:24:45 206 222
2014-07-28 10:11:45 604 202
SQL Time Weighted Average (TWA) Hourly query should look something like this:
Date_time BPS_FIT0161 TWA
2014-07-26 22:00:00 177.4342105
2014-07-26 23:00:00 178
2014-07-27 00:00:00 178
2014-07-27 01:00:00 178
2014-07-27 02:00:00 178
2014-07-27 03:00:00 178
2014-07-27 04:00:00 178
2014-07-27 05:00:00 178
2014-07-27 06:00:00 178
2014-07-27 07:00:00 178
2014-07-27 08:00:00 178
2014-07-27 09:00:00 178
2014-07-27 10:00:00 178
2014-07-27 11:00:00 178
2014-07-27 12:00:00 178
2014-07-27 13:00:00 178
2014-07-27 14:00:00 178
2014-07-27 15:00:00 178
2014-07-27 16:00:00 178
2014-07-27 17:00:00 178
2014-07-27 18:00:00 178
2014-07-27 19:00:00 178
2014-07-27 20:00:00 178
2014-07-27 21:00:00 178
2014-07-27 22:00:00 178
2014-07-27 23:00:00 178
2014-07-28 00:00:00 178
2014-07-28 01:00:00 178
2014-07-28 02:00:00 178
2014-07-28 03:00:00 178
2014-07-28 04:00:00 178
2014-07-28 05:00:00 178
2014-07-28 06:00:00 178
2014-07-28 07:00:00 178
2014-07-28 08:00:00 178
2014-07-28 09:00:00 179.5349202
2014-07-28 10:00:00 202.0857852
Thank you so much for your help!
http://sqlfiddle.com/#!6/a8db7/1
Beginning of solutions
Using VKP's Solution
SELECT dateadd(hour, datediff(hour, 0, Time_Stamp),0) as Date_Time,
sum(time_stamp_ms * bps_fit0161)/sum(time_stamp_ms) as weighted_avg
FROM BPS
WHERE Time_Stamp BETWEEN CONVERT(DATETIME, '2014-07-26 00:00:00', 102)
AND CONVERT(DATETIME, '2014-07-30 00:00:00', 102)
group by dateadd(hour, datediff(hour, 0, Time_Stamp),0),
dateadd(day,datediff(day, 0, Time_Stamp),0)
order by dateadd(hour, datediff(hour, 0, Time_Stamp),0),
dateadd(day,datediff(day, 0, Time_Stamp),0)
My Query's Result
Date_Time weighted_avg
2014-07-26 00:00:00.000 180
2014-07-26 01:00:00.000 113
2014-07-26 02:00:00.000 147
2014-07-26 03:00:00.000 221
2014-07-26 04:00:00.000 252
2014-07-26 05:00:00.000 379
2014-07-26 06:00:00.000 370
2014-07-26 07:00:00.000 253
2014-07-26 08:00:00.000 125
2014-07-26 09:00:00.000 119
2014-07-26 10:00:00.000 125
2014-07-26 11:00:00.000 117
2014-07-26 12:00:00.000 160
2014-07-26 13:00:00.000 123
2014-07-26 14:00:00.000 86
2014-07-26 15:00:00.000 81
2014-07-26 16:00:00.000 100
2014-07-26 17:00:00.000 108
2014-07-26 18:00:00.000 175
2014-07-26 19:00:00.000 238
2014-07-26 20:00:00.000 211
2014-07-26 21:00:00.000 231
2014-07-26 22:00:00.000 173
2014-07-26 23:00:00.000 178
2014-07-27 00:00:00.000 178
2014-07-27 01:00:00.000 178 <----- Start of missing Data!
2014-07-27 03:00:00.000 178
2014-07-27 05:00:00.000 178
2014-07-27 07:00:00.000 178
2014-07-27 09:00:00.000 178
2014-07-27 12:00:00.000 178
2014-07-27 16:00:00.000 178
2014-07-27 20:00:00.000 178
2014-07-28 00:00:00.000 178
2014-07-28 06:00:00.000 178
2014-07-28 09:00:00.000 160
2014-07-28 10:00:00.000 134
2014-07-28 11:00:00.000 113
2014-07-28 12:00:00.000 136
2014-07-28 13:00:00.000 131
2014-07-28 14:00:00.000 84
2014-07-28 15:00:00.000 102
As you can see I am missing hours due to our database being offline or wireless nodes on my network losing communication. What would you change in the above query to auto fill missing hours with the previous hours data, the same goes for missing data for days.
declare @s datetime
declare @e datetime
set @s = '2014-07-26 00:00:00'
set @e = '2014-07-30 00:00:00'
;with x(n) as
(
SELECT TOP (DATEDIFF(HOUR, @s, @e) + 1)
rn = ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_columns ORDER BY [object_id]
)
select DATEADD(HOUR, n-1, @s) as dt into t from x
;with y as (
SELECT
row_number() over(order by t.dt) as rn,
t.dt,
sum(time_stamp_ms * bps_fit0161) / sum(time_stamp_ms) as weighted_avg
FROM BPS
right join t on t.dt = dateadd(hour, datediff(hour, 0, Time_Stamp),0)
group by t.dt,dateadd(hour, datediff(hour, 0, Time_Stamp),0)
)
select y.dt ,
case when y.weighted_avg is null then prev_y.weighted_avg
else y.weighted_avg end as weighted_avg
from y
left join y prev_y on y.rn = prev_y.rn-1
Try this. This groups by the start of any hour till the end of that hour.
Edited: To include all the hours between specified times. This may get you closer to what you are looking for.