Följande fråga hittar perioderna i data, enligt din definition. Den använder först korrelerade underfrågor för att avgöra om en post är början på en period (det vill säga ingen överlappning med tidigare tidsperioder). Den tilldelar sedan "periodStart" som den senaste starten som är början på en icke-överlappande period.
Följande (otestad) fråga använder detta tillvägagångssätt:
with TimeWithOverlap as (
select t.*,
(case when exists (select * from dbo.Available tbefore where t.availStart > tbefore.availStart and tbefore.availEnd >= t.availStart)
then 0
else 1
end) as IsPeriodStart
from dbo.Available t
),
TimeWithPeriodStart as (
select two.*,
(select MAX(two1.AvailStart) from TimeWithOverlap two1 where IsPeriodStart = 1 and two1.AvailStart <= two.AvailStart
) as periodStart
from TimeWithOverlap two
)
select periodStart, MAX(AvailEnd) as periodEnd
from TimeWithPeriodStart twps
group by periodStart;
http://sqlfiddle.com/#!6/3483c/20 (Andra frågan)
Om två perioder båda startar samtidigt, så fungerar det fortfarande, eftersom AvailStart-värdena är desamma. På grund av de korrelerade underfrågorna kanske detta inte fungerar särskilt bra på ens medelstora datamängder.
Det finns andra metoder för att närma sig detta. Om du till exempel hade SQL Server 2012 skulle du kunna använda kumulativa summafunktioner, som erbjuder en enklare metod.