В этом ответе предполагается, что вы используете SQL Server. Ваш образец «на первый час» на самом деле включает в себя больше, чем первый час; он должен остановиться после строки 00: 10: 00.1, я думаю.
Вы можете найти предыдущую строку для каждой строки, присоединившись к самой таблице, затем присоединившись к другому разу и сказав, что между первыми двумя строками ничего не может быть:
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
Это дает вам сумму за период. Для расчета общего количества часов необходимо разделить записи, которые пересекают границу часов. Вы можете сделать это, добавив запись для конца каждого часа, например:
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))
Вы можете объединить оба запроса, используя оператор WITH для расчета суммы за час:
;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)
Результат:
hour volume
4 285340,5
5 273288,5
6 255408,3
7 5701,2
Вот пример набора данных, который я создал из вашего поста:
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 )