あなたはLEAD
を使用してそれを行うことができ、SQL Serverの2012+から入手LAG
ウィンドウ関数:
;WITH CTE AS (
SELECT ID,
LAG(DateEnd) OVER (PARTITION BY ID ORDER BY DateEnd) AS PrevEnd,
DateStart,
DateEnd,
LEAD(DateStart) OVER (PARTITION BY ID ORDER BY DateEnd) AS NextStart
FROM DatesTable
)
SELECT ID, DateStart, DateEnd
FROM (
-- Get interval right before current [DateStart, DateEnd] interval
SELECT ID,
CASE
WHEN DateStart IS NULL THEN '20150101'
WHEN DateStart > start THEN start
ELSE NULL
END AS DateStart,
CASE
WHEN DateStart IS NULL THEN '20151231'
WHEN DateStart > start THEN DATEADD(d, -1, DateStart)
ELSE NULL
END AS DateEnd
FROM CTE
CROSS APPLY (SELECT COALESCE(DATEADD(d, 1, PrevEnd), '20150101')) x(start)
-- If there is no next interval then get interval right after current
-- [DateStart, DateEnd] interval (up-to end of year)
UNION ALL
SELECT ID, DATEADD(d, 1, DateEnd) AS DateStart, '20151231' AS DateEnd
FROM CTE
WHERE DateStart IS NOT NULl -- Do not re-examine [Null, Null] interval
AND NextStart IS NULL -- There is no next [DateStart, DateEnd] interval
AND DateEnd < '20151231' -- Current [DateStart, DateEnd] interval
-- does not terminate on 31/12/2015
) AS t
WHERE t.DateStart IS NOT NULL
ORDER BY ID, DateStart
上記のクエリの背後にある考え方は単純で、すべての[DateStart, DateEnd]
間隔はを得るため間隔権利「を働いていません」その前に。現在のインターバルの後にインターバルがない場合は、'not worked'のインターバル(インターバルがある場合)を取得します。
はまた、私はDateStart
がNULL
であるならば、DateStart
も同じID
ためNULL
であることを前提としています。
Demo here
レコードID = 3のような結果の論理を説明できますか? –
これはSQL Server 2008の痛みです.SQL Server 2012にアップグレードできますか? –
これを検討してください。それが役に立ったら、2012年にこれを実行できます。 – Brian