次のクエリは、定義に従って、データ内の期間を検索します。最初に相関サブクエリを使用して、レコードが期間の開始であるかどうか (つまり、以前の期間と重複していないかどうか) を判断します。次に、重複しない期間の開始点である最新の開始点として「periodStart」を割り当てます。
次の (テストされていない) クエリは、このアプローチを採用しています:
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 (2 番目のクエリ)
2 つの期間が同時に開始された場合でも、AvailStart の値が同じであるため、機能します。サブクエリが相関しているため、これは中規模のデータセットでもうまく機能しない可能性があります。
これにアプローチする方法は他にもあります。たとえば、SQL Server 2012 を使用している場合は、より単純な方法を提供する累積合計関数を使用できます。