在同一行上汇总多个赋值

时间:2017-12-15 15:22:30

标签: sql-server tsql sql-server-2008-r2

MSSQL - 2008r2

我有以下数据集

enter image description here

正如您所看到的,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')

3 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分:1)

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

SQL DEMO

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 
;

<强>输出

enter image description here