在时间轴SQL Server中对事件进行分组

时间:2017-09-19 22:55:28

标签: sql-server tsql

我有一系列按时间顺序互相跟随的事件。为了方便起见,我将事件四舍五入到1分钟。有时同一事件发生在同一事件之后,基本上使它成为同一事件。

基础数据如下所示:

enter image description here

    create table #Events (StartTime datetime,EndTime datetime,Activity varchar(55)) insert into #Events (Start,End,Activity) select '2017/09/19 10:01','2017/09/19 10:15','Play' insert into #Events (Start,End,Activity) select '2017/09/19 10:16','2017/09/19 11:00','Subject 1' insert into #Events (Start,End,Activity) select '2017/09/19 11:01','2017/09/19 11:12','Subject 1' insert into #Events (Start,End,Activity) select '2017/09/19 11:13','2017/09/19 11:15','Play' insert into #Events (Start,End,Activity) select '2017/09/19 11:16','2017/09/19 11:25','Play' insert into #Events (Start,End,Activity) select '2017/09/19 11:26','2017/09/19 12:14','Subject 2' insert into #Events (Start,End,Activity) select '2017/09/19 12:15','2017/09/19 12:25','Subject 2' insert into #Events (Start,End,Activity) select '2017/09/19 12:26','2017/09/19 12:35','Subject 2' insert into #Events (Start,End,Activity) select '2017/09/19 12:36','2017/09/19 12:45','Play' 

我想要一个如下所示的结果集: enter image description here

实现这一目标的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

一种方法是使用行号的差异来对活动岛进行分组。例如:

SELECT Start = MIN(StartTime), [End] = MAX(EndTime), Activity
FROM (
    SELECT *, RN = ROW_NUMBER() OVER (ORDER BY StartTime) - ROW_NUMBER() OVER (PARTITION BY Activity ORDER BY StartTime)
    FROM #Events
) AS E
GROUP BY Activity, RN;

答案 1 :(得分:0)

简单,

Select 
min(StartTime) start
,Max(EndDate) end
,Activity 

from #Events
    group by Activity

答案 2 :(得分:0)

我希望这是最好的方式:

SELECT  X.Start, Y.[End], X.Activity
FROM
(
    SELECT ROW_NUMBER() OVER (ORDER BY E1.StartTime) RN, E1.StartTime [Start], E1.Activity
    FROM (
        SELECT *, ROW_NUMBER() OVER (ORDER BY StartTime) RN
        FROM #Events
    ) AS E1
    LEFT JOIN
    (
        SELECT *, ROW_NUMBER() OVER (ORDER BY StartTime) RN
        FROM #Events
    ) AS E2
    ON E1.Activity=E2.Activity
    AND E1.RN=E2.RN+1
    WHERE E2.Activity IS NULL
) X
INNER JOIN
(
    SELECT ROW_NUMBER() OVER (ORDER BY E1.StartTime) RN, E1.EndTime [End], E1.Activity
    FROM (
        SELECT *, ROW_NUMBER() OVER (ORDER BY StartTime) RN
        FROM #Events
    ) AS E1
    LEFT JOIN
    (
        SELECT *, ROW_NUMBER() OVER (ORDER BY StartTime) RN
        FROM #Events
    ) AS E2
    ON E1.Activity=E2.Activity
    AND E1.RN=E2.RN-1
    WHERE E2.Activity IS NULL
) Y
ON X.RN=Y.RN

结果:

2017-09-19 10:01:00.000 2017-09-19 10:15:00.000 Play
2017-09-19 10:16:00.000 2017-09-19 11:12:00.000 Subject 1
2017-09-19 11:13:00.000 2017-09-19 11:25:00.000 Play
2017-09-19 11:26:00.000 2017-09-19 12:35:00.000 Subject 2
2017-09-19 12:36:00.000 2017-09-19 12:45:00.000 Play