Вот один из подходов. Запрос выбирает все строки из таблицы, а затем использует outer apply
для суммирования последнего значения для устройства. Запрос not exists
отфильтровывает строки, которые не являются последней строкой для этого устройства.
select t1.timestamp
, last_rows_per_device.Total
from @t t1
outer apply
(
select sum(t2.value) as Total
from @t t2
where (
t2.timestamp < t1.timestamp
or (t2.timestamp = t1.timestamp and t2.device <= t1.device)
)
and not exists
(
select *
from @t t3
where t3.device = t2.device
and t2.timestamp < t3.timestamp
and t3.timestamp <= t1.timestamp
)
) last_rows_per_device
order by
t1.timestamp
, t1.device
В запросе предполагается, что (timestamp, device)
уникален, и он упорядочивает строки с одинаковой отметкой времени по идентификатору устройства, сначала наименьшее устройство.
Это соответствует вашему примеру вывода:
timestamp Total
2010-12-30 00:00 5
2010-12-30 00:05 5
2010-12-30 00:05 15
2010-12-30 00:13 33
2010-12-30 00:16 44
2010-12-30 00:30 43
2010-12-30 00:40 77
2010-12-30 00:40 89
2010-12-30 00:45 46
2010-12-30 10:00 67
Исходные данные:
declare @t table (timestamp datetime, device int, value int)
insert @t (timestamp, device, value)
select '2010-12-30 00:00', 1, 5
union all select '2010-12-30 00:05', 1, 5
union all select '2010-12-30 00:05', 2, 10
union all select '2010-12-30 00:13', 1, 23
union all select '2010-12-30 00:16', 3, 11
union all select '2010-12-30 00:30', 1, 22
union all select '2010-12-30 00:40', 2, 55
union all select '2010-12-30 00:40', 3, 12
union all select '2010-12-30 00:45', 2, 12
union all select '2010-12-30 10:00', 3, 33