我有以下数据集:
;with Data AS
(
select '001' AS PERSONNUM,'2017-09-18 00:00:00.000' AS START,'2017-09-21 00:00:00.000' AS [END]
UNION
select '001','2017-09-22 00:00:00.000' AS START,'2017-09-22 00:00:00.000' AS [END]
UNION
select '002','2017-09-18 00:00:00.000' AS START,'2017-09-20 00:00:00.000' AS [END]
UNION
select '002','2017-09-22 00:00:00.000' AS START,'2017-09-22 00:00:00.000' AS [END]
)
select * from Data
如果某个员工(PERSONNUM)的START列与下一行的END列和上一列的END列之间的天数差异等于1,我需要合并记录。在我的示例中,对于人员' 001'记录应该合并,对于人员#002;' - 没有变化。
因此,预期结果如下:
提前谢谢!
答案 0 :(得分:2)
沿着这条线的东西...基本上直接来自Itzik Ben-Gan's New Solution to the Packing Intervals Problem
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
PersonId CHAR(3),
BegDT DATETIME,
EndDT DATETIME
);
INSERT #TestData(PersonId, BegDT, EndDT) VALUES
(1, '20151231 08:00:00', '20151231 08:30:00'),
(1, '20151231 08:30:00', '20151231 09:00:00'),
(1, '20151231 09:00:00', '20151231 09:30:00'),
(1, '20151231 10:00:00', '20151231 11:00:00'),
(1, '20151231 10:30:00', '20151231 12:00:00'),
(1, '20151231 11:30:00', '20151231 12:30:00'),
(2, '20151231 08:00:00', '20151231 10:30:00'),
(2, '20151231 08:30:00', '20151231 10:00:00'),
(2, '20151231 09:00:00', '20151231 09:30:00'),
(2, '20151231 11:00:00', '20151231 11:30:00'),
(2, '20151231 11:32:00', '20151231 12:00:00'),
(2, '20151231 12:04:00', '20151231 12:30:00'),
(3, '20151231 08:00:00', '20151231 09:00:00'),
(3, '20151231 08:00:00', '20151231 08:30:00'),
(3, '20151231 08:30:00', '20151231 09:00:00'),
(3, '20151231 09:30:00', '20151231 09:30:00');
WITH
cte_MPE AS (
SELECT
td.PersonId, td.BegDT, td.EndDT,
MaxPrevEnd = MAX(td.EndDT) OVER (PARTITION BY td.PersonId ORDER BY td.BegDT, td.EndDT ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
FROM
#TestData td
),
cte_DivGroup AS (
SELECT
m.PersonId, m.BegDT, m.EndDT, m.MaxPrevEnd,
DivGroup = SUM(x.NewBeg) OVER (PARTITION BY m.PersonId ORDER BY m.BegDT, m.EndDT ROWS UNBOUNDED PRECEDING)
FROM
cte_MPE m
CROSS APPLY ( VALUES (IIF(m.BegDT <= m.MaxPrevEnd, NULL, 1)) ) x (NewBeg)
)
SELECT
dg.PersonId,
BegDT = MIN(dg.BegDT),
EndDT = MAX(dg.EndDT)
FROM
cte_DivGroup dg
GROUP BY
dg.PersonId,
dg.DivGroup
ORDER BY
dg.PersonId;
结果...
PersonId BegDT EndDT
-------- ----------------------- -----------------------
1 2015-12-31 08:00:00.000 2015-12-31 09:30:00.000
1 2015-12-31 10:00:00.000 2015-12-31 12:30:00.000
2 2015-12-31 08:00:00.000 2015-12-31 10:30:00.000
2 2015-12-31 11:00:00.000 2015-12-31 11:30:00.000
2 2015-12-31 11:32:00.000 2015-12-31 12:00:00.000
2 2015-12-31 12:04:00.000 2015-12-31 12:30:00.000
3 2015-12-31 08:00:00.000 2015-12-31 09:00:00.000
3 2015-12-31 09:30:00.000 2015-12-31 09:30:00.000