在同一行上汇总多个作业

问题描述 投票:0回答:3

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')
sql-server tsql sql-server-2008-r2
3个回答
2
投票

使用 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

1
投票

如果你想获得每个连续的范围,你需要一个递归 cte。

SQL 演示

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 
;

输出


1
投票

用这个

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
© www.soinside.com 2019 - 2024. All rights reserved.