. . CROSS APPLY. SQLFiddle .
DECLARE @Durations TABLE (ID int IDENTITY(1,1), StartTime datetime, EndTime datetime);
INSERT INTO @Durations VALUES
('2015-01-01 21:05:00', '2015-01-01 22:09:00'),
('2015-01-01 01:05:00', '2015-01-01 01:20:00'),
('2015-01-01 11:05:00', '2015-01-01 13:09:00'),
('2015-01-01 15:05:00', '2015-01-01 17:50:00'),
('2015-01-01 16:30:00', '2015-01-01 17:20:00');
datetime , varchar datetime.
. , . 24. .
DECLARE @Numbers TABLE (Number int);
INSERT INTO @Numbers VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
datetime. -, .
DECLARE @VarStart datetime;
SET @VarStart = '2000-01-01';
-
SELECT *
FROM
@Durations AS D
CROSS APPLY
(
SELECT N.Number
FROM @Numbers AS N
WHERE N.Number <= DATEDIFF(hour, StartTime, EndTime)
) AS CA_Number
ORDER BY ID;
ID StartTime EndTime Number
1 2015-01-01 21:05:00 2015-01-01 22:09:00 0
1 2015-01-01 21:05:00 2015-01-01 22:09:00 1
2 2015-01-01 01:05:00 2015-01-01 01:20:00 0
3 2015-01-01 11:05:00 2015-01-01 13:09:00 0
3 2015-01-01 11:05:00 2015-01-01 13:09:00 1
3 2015-01-01 11:05:00 2015-01-01 13:09:00 2
4 2015-01-01 15:05:00 2015-01-01 17:50:00 0
4 2015-01-01 15:05:00 2015-01-01 17:50:00 1
4 2015-01-01 15:05:00 2015-01-01 17:50:00 2
5 2015-01-01 16:30:00 2015-01-01 17:20:00 0
5 2015-01-01 16:30:00 2015-01-01 17:20:00 1
, . - .
SELECT *
,DATEDIFF(minute, MaxStart, MinEnd) AS MinutesPerHour
FROM
@Durations AS D
CROSS APPLY
(
SELECT N.Number
FROM @Numbers AS N
WHERE N.Number <= DATEDIFF(hour, StartTime, EndTime)
) AS CA_Number
CROSS APPLY
(
SELECT
DATEADD(hour, CA_Number.Number, StartTime) AS HourStart
,DATEADD(hour, CA_Number.Number+1, StartTime) AS HourEnd
) AS CA_HourEnd
CROSS APPLY
(
SELECT
DATEADD(hour, DATEDIFF(hour, @VarStart, HourStart), @VarStart) AS HourStartFinal
,DATEADD(hour, DATEDIFF(hour, @VarStart, HourEnd), @VarStart) AS HourEndFinal
) AS CA_HourEndFinal
CROSS APPLY
(
SELECT
CASE WHEN StartTime > HourStartFinal THEN StartTime ELSE HourStartFinal END AS MaxStart
,CASE WHEN EndTime < HourEndFinal THEN EndTime ELSE HourEndFinal END AS MinEnd
) AS CA_Intersect
ORDER BY ID;
CA_HourEnd CA_HourEndFinal Number. . :
ID StartTime EndTime Number HourStart HourEnd HourStartFinal HourEndFinal MaxStart MinEnd MinutesPerHour
1 2015-01-01 21:05:00 2015-01-01 22:09:00 0 2015-01-01 21:05:00 2015-01-01 22:05:00 2015-01-01 21:00:00 2015-01-01 22:00:00 2015-01-01 21:05:00 2015-01-01 22:00:00 55
1 2015-01-01 21:05:00 2015-01-01 22:09:00 1 2015-01-01 22:05:00 2015-01-01 23:05:00 2015-01-01 22:00:00 2015-01-01 23:00:00 2015-01-01 22:00:00 2015-01-01 22:09:00 9
2 2015-01-01 01:05:00 2015-01-01 01:20:00 0 2015-01-01 01:05:00 2015-01-01 02:05:00 2015-01-01 01:00:00 2015-01-01 02:00:00 2015-01-01 01:05:00 2015-01-01 01:20:00 15
3 2015-01-01 11:05:00 2015-01-01 13:09:00 0 2015-01-01 11:05:00 2015-01-01 12:05:00 2015-01-01 11:00:00 2015-01-01 12:00:00 2015-01-01 11:05:00 2015-01-01 12:00:00 55
3 2015-01-01 11:05:00 2015-01-01 13:09:00 1 2015-01-01 12:05:00 2015-01-01 13:05:00 2015-01-01 12:00:00 2015-01-01 13:00:00 2015-01-01 12:00:00 2015-01-01 13:00:00 60
3 2015-01-01 11:05:00 2015-01-01 13:09:00 2 2015-01-01 13:05:00 2015-01-01 14:05:00 2015-01-01 13:00:00 2015-01-01 14:00:00 2015-01-01 13:00:00 2015-01-01 13:09:00 9
4 2015-01-01 15:05:00 2015-01-01 17:50:00 0 2015-01-01 15:05:00 2015-01-01 16:05:00 2015-01-01 15:00:00 2015-01-01 16:00:00 2015-01-01 15:05:00 2015-01-01 16:00:00 55
4 2015-01-01 15:05:00 2015-01-01 17:50:00 1 2015-01-01 16:05:00 2015-01-01 17:05:00 2015-01-01 16:00:00 2015-01-01 17:00:00 2015-01-01 16:00:00 2015-01-01 17:00:00 60
4 2015-01-01 15:05:00 2015-01-01 17:50:00 2 2015-01-01 17:05:00 2015-01-01 18:05:00 2015-01-01 17:00:00 2015-01-01 18:00:00 2015-01-01 17:00:00 2015-01-01 17:50:00 50
5 2015-01-01 16:30:00 2015-01-01 17:20:00 0 2015-01-01 16:30:00 2015-01-01 17:30:00 2015-01-01 16:00:00 2015-01-01 17:00:00 2015-01-01 16:30:00 2015-01-01 17:00:00 30
5 2015-01-01 16:30:00 2015-01-01 17:20:00 1 2015-01-01 17:30:00 2015-01-01 18:30:00 2015-01-01 17:00:00 2015-01-01 18:00:00 2015-01-01 17:00:00 2015-01-01 17:20:00 20
, :
SELECT
HourStartFinal
,SUM(DATEDIFF(minute, MaxStart, MinEnd)) AS SumMinutesPerHour
FROM
@Durations AS D
CROSS APPLY
(
SELECT N.Number
FROM @Numbers AS N
WHERE N.Number <= DATEDIFF(hour, StartTime, EndTime)
) AS CA_Number
CROSS APPLY
(
SELECT
DATEADD(hour, CA_Number.Number, StartTime) AS HourStart
,DATEADD(hour, CA_Number.Number+1, StartTime) AS HourEnd
) AS CA_HourEnd
CROSS APPLY
(
SELECT
DATEADD(hour, DATEDIFF(hour, @VarStart, HourStart), @VarStart) AS HourStartFinal
,DATEADD(hour, DATEDIFF(hour, @VarStart, HourEnd), @VarStart) AS HourEndFinal
) AS CA_HourEndFinal
CROSS APPLY
(
SELECT
CASE WHEN StartTime > HourStartFinal THEN StartTime ELSE HourStartFinal END AS MaxStart
,CASE WHEN EndTime < HourEndFinal THEN EndTime ELSE HourEndFinal END AS MinEnd
) AS CA_Intersect
GROUP BY HourStartFinal
ORDER BY HourStartFinal;
HourStartFinal SumMinutesPerHour
2015-01-01 01:00:00.000 15
2015-01-01 11:00:00.000 55
2015-01-01 12:00:00.000 60
2015-01-01 13:00:00.000 9
2015-01-01 15:00:00.000 55
2015-01-01 16:00:00.000 90
2015-01-01 17:00:00.000 70
2015-01-01 21:00:00.000 55
2015-01-01 22:00:00.000 9
SQLFiddle