Благодаря предыдущим ответам я получил представление о том, как выполнить все требования.
Для каждой записи я вычисляю разницу во времени с последней записью в миллисекундах (или секундах, в зависимости от разрешения). Затем я делаю разницу по модулю на промежуток времени, который меня интересует (например, 3600 с = 1 час).
Затем я добавляю это значение к time_col той же записи и группирую по нему.
Создать таблицу:
CREATE TABLE [dbo].[test_table](
[value_col] [int] NOT NULL,
[time_col] [datetime] NOT NULL
) ON [PRIMARY]
GO
INSERT [dbo].[test_table] ([value_col], [time_col]) VALUES (3, CAST(0x00009E8C01705737 AS DateTime))
INSERT [dbo].[test_table] ([value_col], [time_col]) VALUES (2, CAST(0x00009E8C015FDD8B AS DateTime))
INSERT [dbo].[test_table] ([value_col], [time_col]) VALUES (15, CAST(0x00009E8C015FDC77 AS DateTime))
INSERT [dbo].[test_table] ([value_col], [time_col]) VALUES (6, CAST(0x00009E8C0180D1F6 AS DateTime))
Решение для SQL:
SELECT SUM(value_col) AS s_val, aggregation_time FROM
(SELECT value_col, time_col,
DATEADD(millisecond,DATEDIFF(millisecond,time_col,(SELECT MAX(time_col)
FROM test_table)) % (3600 * 1000), time_col) AS aggregation_time
FROM test_table)
GROUP BY aggregation_time
ORDER BY aggregation_time DESC
Решение для Oracle:
SELECT SUM(value_col) as s_val, aggregation_time FROM
(SELECT value_col, time_col +
(MOD(ROUND(((CAST((SELECT MAX(time_col) FROM test_table) AS DATE ) -
CAST(time_col AS DATE ))*86400),0),3600))/86400 as aggregation_time
FROM test_table l)
GROUP BY aggregation_time
ORDER BY aggregation_time DESC
Если я хочу агрегировать за последние 2 часа, я просто изменяю 3600 на 7200 секунд.
Результат:
9 2011-02-16 23:21:05.247
17 2011-02-16 22:21:05.247