2014-12-19 19 views
1
新的一天

轉變的開始日期我有一個包含一些轉變信息的僱員(S)查詢時間序列,更新每一行與重疊到

+-------+------------+------------------+------------+------------------+------------+ 
| empid | StartDate | StartTime  | EndDate |  EndTime  | ShiftDate | 
+-------+------------+------------------+------------+------------------+------------+ 
| 391 | 2014-12-16 | 20:00:00.0000000 | 2014-12-16 | 22:00:00.0000000 | ?   | 
| 391 | 2014-12-16 | 22:00:00.0000000 | 2014-12-16 | 22:15:00.0000000 | ?   | 
| 391 | 2014-12-16 | 22:15:00.0000000 | 2014-12-17 | 00:00:00.0000000 | ?   | 
| 391 | 2014-12-17 | 00:00:00.0000000 | 2014-12-17 | 00:45:00.0000000 | ?   | 
| 391 | 2014-12-17 | 00:45:00.0000000 | 2014-12-17 | 02:30:00.0000000 | ?   | 
| 391 | 2014-12-17 | 02:30:00.0000000 | 2014-12-17 | 02:45:00.0000000 | ?   | 
| 391 | 2014-12-17 | 02:45:00.0000000 | 2014-12-17 | 04:30:00.0000000 | ?   | 
+-------+------------+------------------+------------+------------------+------------+ 
| 391 | 2014-12-17 | 20:00:00.0000000 | 2014-12-17 | 21:45:00.0000000 | ?   | 
| 391 | 2014-12-17 | 21:45:00.0000000 | 2014-12-17 | 22:00:00.0000000 | ?   | 
| 391 | 2014-12-17 | 22:00:00.0000000 | 2014-12-18 | 00:00:00.0000000 | ?   | 
| 391 | 2014-12-18 | 00:00:00.0000000 | 2014-12-18 | 00:45:00.0000000 | ?   | 
| 391 | 2014-12-18 | 00:45:00.0000000 | 2014-12-18 | 02:30:00.0000000 | ?   | 
| 391 | 2014-12-18 | 02:30:00.0000000 | 2014-12-18 | 02:45:00.0000000 | ?   | 
| 391 | 2014-12-18 | 02:45:00.0000000 | 2014-12-18 | 04:30:00.0000000 | ?   | 
+-------+------------+------------------+------------+------------------+------------+ 

表我需要更新ShiftDate列與這個班次的StartDate。所以下面是2個不同的班次,每個班次超過2天。第一班ShiftDate每行應該是2014-12-16,第二班,每行的ShiftDate應該是2014-12-17。

預期結果:

+-------+------------+------------------+------------+------------------+------------+ 
| empid | StartDate | StartTime  | EndDate |  EndTime  | ShiftDate | 
+-------+------------+------------------+------------+------------------+------------+ 
| 391 | 2014-12-16 | 20:00:00.0000000 | 2014-12-16 | 22:00:00.0000000 | 2014-12-16 | 
| 391 | 2014-12-16 | 22:00:00.0000000 | 2014-12-16 | 22:15:00.0000000 | 2014-12-16 | 
| 391 | 2014-12-16 | 22:15:00.0000000 | 2014-12-17 | 00:00:00.0000000 | 2014-12-16 | 
| 391 | 2014-12-17 | 00:00:00.0000000 | 2014-12-17 | 00:45:00.0000000 | 2014-12-16 | 
| 391 | 2014-12-17 | 00:45:00.0000000 | 2014-12-17 | 02:30:00.0000000 | 2014-12-16 | 
| 391 | 2014-12-17 | 02:30:00.0000000 | 2014-12-17 | 02:45:00.0000000 | 2014-12-16 | 
| 391 | 2014-12-17 | 02:45:00.0000000 | 2014-12-17 | 04:30:00.0000000 | 2014-12-16 | 
+-------+------------+------------------+------------+------------------+------------+ 
| 391 | 2014-12-17 | 20:00:00.0000000 | 2014-12-17 | 21:45:00.0000000 | 2014-12-17 | 
| 391 | 2014-12-17 | 21:45:00.0000000 | 2014-12-17 | 22:00:00.0000000 | 2014-12-17 | 
| 391 | 2014-12-17 | 22:00:00.0000000 | 2014-12-18 | 00:00:00.0000000 | 2014-12-17 | 
| 391 | 2014-12-18 | 00:00:00.0000000 | 2014-12-18 | 00:45:00.0000000 | 2014-12-17 | 
| 391 | 2014-12-18 | 00:45:00.0000000 | 2014-12-18 | 02:30:00.0000000 | 2014-12-17 | 
| 391 | 2014-12-18 | 02:30:00.0000000 | 2014-12-18 | 02:45:00.0000000 | 2014-12-17 | 
| 391 | 2014-12-18 | 02:45:00.0000000 | 2014-12-18 | 04:30:00.0000000 | 2014-12-17 | 

+ ------- + ------------ + -------------- ---- + ------------ + ------------------ + ------------ +

我無法處理從給定行中確定移位日期的方法。當這是一個新班次時,班次開始時間將不會與班次的前一個結束時間相同。

我與SQL 2008 R2

任何建議的工作讓我朝着正確的方向將是巨大的!

+1

可以更新與預期輸出 – 2014-12-19 04:09:11

+0

增加的預期結果的問題,也許是一個更好的列名應的被ShiftStartDate – kirkdmo 2014-12-19 04:14:48

+0

我看不出你如何能做到這一點 - 你怎麼知道,這兩個塊是一除了通過檢查以外的其他轉變? – Rikalous 2014-12-19 09:35:14

回答

1

使用遞歸CTE:

;WITH 
    CTE1 AS 
    (
     SELECT empid, StartDate, StartTime, EndDate, EndTime, 
       ROW_NUMBER() OVER (PARTITION BY empid ORDER BY StartDate, StartTime) AS RowNumber 
     FROM EmployeeShift 
    ), 
    CTE2 AS (
     SELECT empid, StartDate, StartTime, EndDate, EndTime, 
       StartDate AS ShiftDate, 
       RowNumber 
     FROM CTE1 
     WHERE RowNumber = 1 

     UNION ALL 

     SELECT c1.empid, c1.StartDate, c1.StartTime, c1.EndDate, c1.EndTime, 
       CASE 
        WHEN c1.StartDate = c2.EndDate AND c1.StartTime = c2.EndTime THEN c2.ShiftDate 
        ELSE c1.StartDate 
       END AS ShiftDate, 
       c1.RowNumber 
     FROM CTE1 c1 
     INNER JOIN CTE2 c2 ON c1.empid = c2.empid AND c1.RowNumber = c2.RowNumber + 1 
    ) 

SELECT * FROM CTE2 
OPTION (MAXRECURSION 0) 

一個評註者要求其內部所以這裏有雲:

  1. 每班條目編號爲1,2,3,...,N各員工,並根據其開始和結束日期進行排序。這是CTE1
  2. 對於第一個班次條目,ShiftDate與其StartDate相同。這是CTE2的前半部分。
  3. 從第一個班次條目開始,它遞歸地經歷員工的下一個條目。如果下一個條目的開始時間與先前條目的結束時間相同,則繼續之前的ShiftDate。否則,它將ShiftDate設置爲當前班次的StartDate
+0

這是正確的解決方案,如果@ZoffDino更詳細地描述它的內部組件,它會在更短的時間內變得難以置信。 – Serg 2014-12-19 15:48:39

+0

太棒了!奇蹟般有效! – kirkdmo 2014-12-19 16:25:21