OK, i got it:
DECLARE @tmp TABLE (event_ID INT IDENTITY(1,1) , event_category INT, event_start DATETIME, event_end DATETIME)
INSERT INTO @tmp (event_category, event_start, event_end)
VALUES(1, '2012-12-16 02:02:55', '2012-12-16 02:05:55'),
(2, '2012-12-16 02:05:56', '2012-12-16 02:55:25'),
(1, '2012-12-16 02:55:26', '2012-12-16 03:02:55'),
(2, '2012-12-16 03:02:56', '2012-12-16 03:07:26'),
(1, '2012-12-16 03:07:27', '2012-12-16 04:02:55')
SELECT event_category, interval_start, interval_end,
SUM(CASE
WHEN event_end>interval_end THEN DATEDIFF(ss,event_start, interval_end)
WHEN event_end<interval_end THEN DATEDIFF(ss,event_start, event_end)
ELSE 0
END) AS Duration
FROM(
SELECT event_category, event_start, event_end, DATEADD(hh, DATEDIFF(hh, 0, event_start), 0) AS interval_start, DATEADD(hh, DATEDIFF(hh, 0, event_start)+1, 0) AS interval_end
FROM @tmp
) AS T
GROUP BY event_category, interval_start , interval_end
ORDER BY event_category
Result:
cat interval_start interval_end Duration
1 2012-12-16 02:00:00.000 2012-12-16 03:00:00.000 454
1 2012-12-16 03:00:00.000 2012-12-16 04:00:00.000 3153
2 2012-12-16 02:00:00.000 2012-12-16 03:00:00.000 2969
2 2012-12-16 03:00:00.000 2012-12-16 04:00:00.000 270
NOTE: Some values have been rejected!
For example:
event_id = 3: 2min.55sec
event_id = 5: 2min.55sec
Above values haven't been moved to the next time interval! If you would like to add it, then you need to use CTE[^]
For further information about CTE, please see:
CTE In SQL Server[
^]
Common Table Expressions(CTE) in SQL SERVER 2008[
^]
SQL Server CTE Basics[
^]
CTEs (Common Table Expressions)[
^]
Optimize Recursive CTE Query[
^]
Below CTE:
;WITH MyIntervals AS
(
SELECT event_id, event_category, event_start, event_end, DATEADD(hh, DATEDIFF(hh, 0, event_start), 0) AS interval_start, DATEADD(hh, DATEDIFF(hh, 0, event_start)+1, 0) AS interval_end
FROM @tmp
UNION ALL
SELECT event_id, event_category, interval_end AS event_start, event_end, interval_end AS interval_start, DATEADD(hh, 1, interval_end) AS interval_end
FROM MyIntervals
WHERE event_end>interval_end
)
SELECT event_category, interval_start, interval_end,
SUM(CASE
WHEN event_end>interval_end THEN DATEDIFF(ss,event_start, interval_end)
WHEN event_end<interval_end THEN DATEDIFF(ss,event_start, event_end)
ELSE 0
END) AS Duration
FROM(
SELECT event_category, event_start, event_end, interval_start, interval_end
FROM MyIntervals
) AS T
GROUP BY event_category, interval_start, interval_end
produces the following result:
1 2012-12-16 02:00:00.000 2012-12-16 03:00:00.000 454
1 2012-12-16 03:00:00.000 2012-12-16 04:00:00.000 3328
1 2012-12-16 04:00:00.000 2012-12-16 05:00:00.000 175
2 2012-12-16 02:00:00.000 2012-12-16 03:00:00.000 2969
2 2012-12-16 03:00:00.000 2012-12-16 04:00:00.000 270
Do you see the difference?