MSSQL-2008r2
我有以下数据集
如您所见
V_Key
= 606 已结束多项作业并在同一天再次开始到 B_Key
1(第 1 至 7 行)
同样适用于
V_Key
610 至 B_Key
3(第 8 至 11 行)
我希望能够像这样总结这些行
V_Key B_Key AssignStart AssignEnd
606 1 2017-07-12 14:14:58.000 2017-12-02 16:00:53.000
610 3 2016-02-23 15:01:47.000 NULL
612 4 2017-07-12 14:15:20.000 NULL
625 7 2016-04-01 11:00:00.000 2016-06-14 15:45:00.000
625 9 2016-07-04 11:45:05.000 2016-09-20 09:45:00.000
625 11 2016-09-20 09:45:02.000 2017-01-14 12:05:00.000
提前谢谢您
这是 DDL
CREATE TABLE #temptable (
V_Key BIGINT
, B_Key BIGINT
, AssignStart DATETIME
, AssignEnd DATETIME
);
INSERT INTO #temptable
VALUES
( 606, 1, N'2017-07-12T14:14:58', N'2017-07-20T09:48:20')
, ( 606, 1, N'2017-07-20T09:48:20', N'2017-07-24T10:28:29')
, ( 606, 1, N'2017-07-24T11:39:51', N'2017-09-27T13:16:04')
, ( 606, 1, N'2017-09-27T13:45:52', N'2017-10-06T14:24:09')
, ( 606, 1, N'2017-10-06T14:24:09', N'2017-10-09T10:37:48')
, ( 606, 1, N'2017-10-09T10:37:48', N'2017-11-07T10:25:53')
, ( 606, 1, N'2017-11-07T10:25:53', N'2017-12-02T16:00:53')
, ( 610, 3, N'2016-02-23T15:01:47', N'2016-02-24T10:17:56')
, ( 610, 3, N'2016-02-24T14:21:00', N'2016-04-01T11:57:31')
, ( 610, 3, N'2016-04-01T11:57:33', N'2017-06-14T11:45:56')
, ( 610, 3, N'2017-06-14T11:46:03', NULL)
, ( 612, 4, N'2017-07-12T14:15:20', NULL )
, ( 625, 7, N'2016-04-01T11:00:00', N'2016-06-14T15:45:00')
, ( 625, 9, N'2016-07-04T11:45:05', N'2016-09-20T09:45:00')
, ( 625, 11, N'2016-09-20T09:45:02', N'2017-01-14T12:05:00')
使用 CASE 语句:
select V_Key,
B_Key,
min(AssignStart)as [AssignStart],
CASE WHEN MAX(CASE WHEN AssignEnd IS NULL THEN 1 ELSE 0 END) = 0
THEN MAX(AssignEnd)
END as [AssignEnd]
from #temptable
group by V_Key, B_Key
如果你想获得每个连续的范围,你需要一个递归 cte。
WITH cte as (
SELECT V_Key, B_Key, AssignStart, AssignEnd
FROM #temptable t1
UNION ALL
SELECT t1.V_Key, t1.B_Key, c.AssignStart, t1.AssignEnd
FROM #temptable t1
JOIN cte c
ON t1.AssignStart = c.AssignEnd
), create_ranges as (
SELECT V_key, AssignStart, MAX(AssignEnd) as AssignEnd
FROM cte
GROUP BY V_key, AssignStart
)
SELECT C1.*
FROM create_ranges c1
LEFT JOIN create_ranges c2
ON c1.AssignStart BETWEEN c2.AssignStart AND C2.AssignEnd
AND c1.AssignStart <> c2.AssignStart
AND c1.V_key = c2.V_key
WHERE c2.V_key IS NULL
ORDER BY c1.V_key
;
输出
用这个
SELECT
V_Key,
B_Key,
AssignStart = MIN(AssignStart),
AssignEnd = CASE WHEN MAX(AssignEnd) > MAX(AssignStart)
THEN MAX(AssignEnd)
ELSE NULL END
FROM #temptable
GROUP BY V_Key,B_Key