This answer assumes you are using SQL Server. Your βwithin the first hourβ sample actually includes more than the first hour; it should stop after line 00: 10: 00.1, which I think of.
You can find the previous line for each line by appending it to yourself, then appending a different time, and then there can be nothing between the first two lines:
select StartDate = prev.date , EndDate = cur.date , Milliseconds = datediff(ms,prev.date,cur.date) , Volume = datediff(ms,prev.date,cur.date) / 1000.0 * prev.flow from @flow cur inner join @flow prev on prev.date < cur.date left join @flow inbetween on prev.date < inbetween.date and inbetween.date < cur.date where inbetween.date is null
This gives you the amount for the period. To calculate the total number of hours, you must break the records crossing the hour boundary. You can do this by adding an entry at the end of each hour, for example:
select date, flow from @flow union -- Add end of hour select DATEADD(Hour, DATEDIFF(Hour, 0, date)+1, 0), flow from @flow where date in (select max(date) from @flow group by datepart(hh,date))
You can combine both queries with the WITH statement to calculate the amount per hour:
;with FlowWithHourBounds as ( select date, flow from @flow union -- Add end of hour select DATEADD(Hour, DATEDIFF(Hour, 0, date)+1, 0), flow from @flow where date in ( select max(date) from @flow group by datepart(hh,date)) ) , FlowPerPeriod as ( select StartDate = prev.date , EndDate = cur.date , Milliseconds = datediff(ms,prev.date,cur.date) , Volume = datediff(ms,prev.date,cur.date) / 1000.0 * prev.flow from FlowWithHourBounds cur inner join FlowWithHourBounds prev on prev.date < cur.date left join FlowWithHourBounds inbetween on prev.date < inbetween.date and inbetween.date < cur.date where inbetween.date is null ) select datepart(hh,StartDate), sum(Volume) from FlowPerPeriod group by datepart(hh,StartDate)
Result:
hour volume 4 285340,5 5 273288,5 6 255408,3 7 5701,2
Here is a sample dataset that I created from your post:
declare @flow table ([date] datetime, flow float) insert into @flow values ('2009/10/22 04:00:00.0', 0 ) insert into @flow values ('2009/10/22 04:00:16.2', 23 ) insert into @flow values ('2009/10/22 04:00:20.6', 34 ) insert into @flow values ('2009/10/22 04:00:39.7', 95 ) insert into @flow values ('2009/10/22 04:00:41.7', 97 ) insert into @flow values ('2009/10/22 04:01:15.1', 110) insert into @flow values ('2009/10/22 04:03:17.0', 95 ) insert into @flow values ('2009/10/22 04:06:53.8', 82 ) insert into @flow values ('2009/10/22 04:26:50.7', 77 ) insert into @flow values ('2009/10/22 04:36:50.8', 76 ) insert into @flow values ('2009/10/22 04:46:51.7', 72 ) insert into @flow values ('2009/10/22 04:56:52.2', 74 ) insert into @flow values ('2009/10/22 05:16:52.7', 72 ) insert into @flow values ('2009/10/22 05:26:53.2', 70 ) insert into @flow values ('2009/10/22 05:36:22.1', 84 ) insert into @flow values ('2009/10/22 05:46:16.3', 81 ) insert into @flow values ('2009/10/22 05:56:16.2', 75 ) insert into @flow values ('2009/10/22 06:16:17.3', 73 ) insert into @flow values ('2009/10/22 06:26:16.9', 75 ) insert into @flow values ('2009/10/22 06:36:17.7', 71 ) insert into @flow values ('2009/10/22 06:57:38.7', 57 ) insert into @flow values ('2009/10/22 06:57:48.9', 44 ) insert into @flow values ('2009/10/22 06:57:53.4', 28 ) insert into @flow values ('2009/10/22 06:57:55.3', 12 ) insert into @flow values ('2009/10/22 07:07:55.1', 0 )