Ето решение само за SQL. Използвах DATETIME за колоните. Запазването на времето разделно е грешка според мен, тъй като ще имате проблеми, когато времето мине след полунощ. Можете обаче да коригирате това, за да се справите с тази ситуация, ако е необходимо. Решението също така предполага, че началното и крайното време НЕ са NULL. Отново можете да коригирате според нуждите, ако това не е така.
Общата същност на решението е да получите всички начални времена, които не се припокриват с други интервали, да получите всички крайни времена, които не се припокриват с никакви интервали, след което да съпоставите двете заедно.
Резултатите съвпадат с очакваните резултати, освен в един случай, при който проверката на ръка изглежда, че имате грешка в очаквания резултат. На 6-ти трябва да има интервал, който завършва в 2009-06-06 10:18:45.000.
SELECT
ST.start_time,
ET.end_time
FROM
(
SELECT
T1.start_time
FROM
dbo.Test_Time_Spans T1
LEFT OUTER JOIN dbo.Test_Time_Spans T2 ON
T2.start_time < T1.start_time AND
T2.end_time >= T1.start_time
WHERE
T2.start_time IS NULL
) AS ST
INNER JOIN
(
SELECT
T3.end_time
FROM
dbo.Test_Time_Spans T3
LEFT OUTER JOIN dbo.Test_Time_Spans T4 ON
T4.end_time > T3.end_time AND
T4.start_time <= T3.end_time
WHERE
T4.start_time IS NULL
) AS ET ON
ET.end_time > ST.start_time
LEFT OUTER JOIN
(
SELECT
T5.end_time
FROM
dbo.Test_Time_Spans T5
LEFT OUTER JOIN dbo.Test_Time_Spans T6 ON
T6.end_time > T5.end_time AND
T6.start_time <= T5.end_time
WHERE
T6.start_time IS NULL
) AS ET2 ON
ET2.end_time > ST.start_time AND
ET2.end_time < ET.end_time
WHERE
ET2.end_time IS NULL