Her er en eneste SQL-løsning. Jeg brugte DATETIME til kolonnerne. At gemme tiden adskilt er efter min mening en fejl, da du vil få problemer, når tiderne går over midnat. Du kan dog justere dette for at håndtere den situation, hvis du har brug for det. Løsningen forudsætter også, at start- og sluttidspunkter IKKE er NULL. Igen kan du justere efter behov, hvis det ikke er tilfældet.
Den generelle kerne af løsningen er at få alle starttider, der ikke overlapper med andre spænd, få alle sluttider, der ikke overlapper med nogen spænd, og derefter matche de to sammen.
Resultaterne matcher dine forventede resultater undtagen i ét tilfælde, hvor håndkontrol ser ud til, at du har en fejl i dit forventede output. Den 6. skulle der være et span, der slutter på 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