可以使用LEAD
做到這一點,LAG
可以從SQL Server 2012+窗口功能:
;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]
間隔獲得「沒有工作」區間權在它之前。如果在當前時間間隔之後沒有間隔,那麼也會得到連續的'未工作'間隔(如果有的話)。
另外請注意,我認爲如果DateStart
是NULL
然後DateStart
也NULL
爲同一ID
。
Demo here
你能解釋一下結果的邏輯嗎,比如記錄ID = 3嗎? –
這是SQL Server 2008中的一個痛點。你可以升級到SQL Server 2012嗎? –
考慮完成。如果有幫助,我可以在2012年運行。 – Brian