Následující dotaz najde období v datech podle vaší definice. Nejprve používá korelované poddotazy k určení, zda záznam je začátkem období (to znamená, že se nepřekrývá s dřívějšími časovými obdobími). Poté přiřadí „periodStart“ jako nejnovější začátek, který je začátkem nepřekrývajícího se období.
Následující (netestovaný) dotaz používá tento přístup:
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 (Druhý dotaz)
Pokud dvě období začínají současně, pak to stále funguje, protože hodnoty AvailStart jsou stejné. Kvůli korelovaným poddotazům to nemusí fungovat dobře ani na středně velkých souborech dat.
Existují i jiné metody, jak k tomu přistupovat. Pokud byste například měli SQL Server 2012, mohli byste používat funkce kumulativního součtu, které nabízejí jednodušší metodu.