De volgende query vindt de punten in de gegevens, volgens uw definitie. Het gebruikt eerst gecorreleerde subquery's om te bepalen of een record het begin is van een periode (dat wil zeggen, geen overlap met eerdere tijdsperioden). Het wijst vervolgens de "periodeStart" toe als de meest recente start die het begin is van een niet-overlappende periode.
De volgende (niet-geteste) query volgt deze benadering:
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 (Tweede zoekopdracht)
Als twee perioden beide tegelijkertijd beginnen, werkt het nog steeds, omdat de AvailStart-waarden hetzelfde zijn. Vanwege de gecorreleerde subquery's presteert dit mogelijk niet erg goed, zelfs niet op middelgrote datasets.
Er zijn andere methoden om dit te benaderen. Als u bijvoorbeeld SQL Server 2012 had, zou u cumulatieve somfuncties kunnen gebruiken, die een eenvoudigere methode bieden.