聚合行开始和结束日期 < 10 分钟

Aggregate Rows Start and Finish Date < 10 mins

我想在 SQL 服务器数据库中进行以下转换。

聚合 Tag_of_thing & Status_of_thing 这样...

注意 在这种情况下,结束班次是上面的行,参见示例 tables

  1. If Start_shift_date_time = End_shift_date_time 然后聚合行使得 start = min(Start_shift_date_time ) 和 finish =最大(End_shift_date_time)

  2. 如果 Start_shift_date_time <= End_shift_date_time + 10mins 那么聚合行使得 start = min(Start_shift_date_time ) 和 finish = max(End_shift_date_time )

原始源数据Table(我们称之为table输入)

Tag_of_thing    Status_of_thing Start_shift_date_time   End_shift_date_time Other_column_I_dont_care_about
A123    T123    04/08/2020 15:07:02 04/08/2020 18:00:00 56110
A123    T123    04/08/2020 18:00:00 05/08/2020 01:27:41 32473
A123    T123    05/08/2020 06:15:41 05/08/2020 06:00:00 26808
A123    T124    05/08/2020 06:00:00 05/08/2020 18:00:00 23969
A123    T124    05/08/2020 18:00:00 06/08/2020 06:00:00 29613
A123    T124    06/08/2020 06:00:00 06/08/2020 10:48:00 7276
B124    G1  03/08/2020 12:43:02 03/08/2020 18:00:00 29806
B124    G1  03/08/2020 18:00:00 03/08/2020 23:03:41 46101
B124    G1  03/08/2020 23:07:41 04/08/2020 03:55:41 15510
C124    R1  03/08/2020 12:43:02 03/08/2020 18:00:00 47527
C124    R1  03/08/2020 18:00:00 03/08/2020 23:03:41 16708
C124    R1  03/08/2020 23:18:41 04/08/2020 04:06:41 3247

转换后的输出数据Table

Tag_of_thing    Status_of_thing Start_shift_date_time   End_shift_date_time
A123    T123    04/08/2020 15:07:02 05/08/2020 01:27:41
A123    T123    05/08/2020 06:15:41 05/08/2020 06:00:00
A123    T124    05/08/2020 06:00:00 06/08/2020 10:48:00
B124    G1  03/08/2020 12:43:02 04/08/2020 03:55:41
C124    R1  03/08/2020 12:43:02 03/08/2020 23:03:41
C124    R1  03/08/2020 23:18:41 04/08/2020 04:06:41

如果您需要更多示例或对转换过程的不同解释,请告诉我

资源

类似的间隙和孤岛问题:https://bertwagner.com/2019/03/12/gaps-and-islands/

如果我理解正确,这是一个 gap-and-islands 问题 -- 不同的是,您在行之间允许最多 10 分钟进行聚合。

select tag_of_thing, status_of_thing, grp, min(start_shift_date_time), max(end_shift_date_time) 
from (select t.*,
             sum(case when prev_esdt > dateadd(minute, -10, start_shift_date_time)
                      then 0 else 1
                 end)  over (partition by tag_of_thing, status_of_thing order by start_shift_date_time) as grp
      from (select t.*,
                   lag(end_shift_date_time) over (partition by tag_of_thing, status_of_thing order by start_shift_date_time) as prev_esdt
            from t
           ) t
     ) t
group by tag_of_thing, status_of_thing, grp
order by tag_of_thing, status_of_thing, min(start_shift_date_time);

这通过比较之前的结束时间和当前的开始时间来确定新组的第一行所在的位置。该组然后是这些值的累加和,最后一步是聚合。