我有一张表,其中包含员工的一些班次信息
+-------+------------+------------------+------------+------------------+------------+
| 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 | ? |
+-------+------------+------------------+------------+------------------+------------+
我需要使用StartDate为此班次更新ShiftDate列。所以下面是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 |
+ ------- + ------------ + ------------------ + ------ ------ + ------------------ + ------------ +
我无法确定从给定行确定转换日期的方法。当它是新的班次时,Shift StartTime将永远不会与Shift的前一个EndTime相同。
我正在使用SQL 2008 R2
任何让我朝着正确方向前进的建议都会很棒!
答案 0 :(得分: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)
评论员要求它的内部结构,所以在这里:
CTE1
ShiftDate
与其StartDate
相同。这是CTE2
的上半部分。ShiftDate
。否则,它会将ShiftDate
设置为当前班次StartDate
。