Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL中,根据匹配的结束时间和开始时间组合顺序事件的最佳方法是什么?_Sql_Date_Timestamp_Window Functions_Gaps And Islands - Fatal编程技术网

在SQL中,根据匹配的结束时间和开始时间组合顺序事件的最佳方法是什么?

在SQL中,根据匹配的结束时间和开始时间组合顺序事件的最佳方法是什么?,sql,date,timestamp,window-functions,gaps-and-islands,Sql,Date,Timestamp,Window Functions,Gaps And Islands,我使用的数据库根据零件ID和激活时间记录事件。我遇到的问题是,这些事件会被截断以适应一天之内的情况。如果零件的活动时间延续到第二天,则事件将按其关联的天数进行分割。在这种情况下,第二天的活动开始时间戳与前一天的活动结束时间戳匹配。我试图找到一种方法,将这些分割事件合并成一个记录,每个部分处于活动状态时的“真实”开始和结束时间 以下是数据集外观的示例: date part_id active_start active_end 1/1/2019 100 1/1/19 8:00

我使用的数据库根据零件ID和激活时间记录事件。我遇到的问题是,这些事件会被截断以适应一天之内的情况。如果零件的活动时间延续到第二天,则事件将按其关联的天数进行分割。在这种情况下,第二天的活动开始时间戳与前一天的活动结束时间戳匹配。我试图找到一种方法,将这些分割事件合并成一个记录,每个部分处于活动状态时的“真实”开始和结束时间


以下是数据集外观的示例:

date    part_id   active_start  active_end
1/1/2019    100   1/1/19 8:00   1/1/19 9:30
1/1/2019    100   1/1/19 14:00  1/2/19 0:00
1/2/2019    100   1/2/19 0:00   1/3/19 0:00
1/3/2019    100   1/3/19 0:00   1/4/19 0:00
1/4/2019    100   1/4/19 0:00   1/4/19 8:00
1/7/2019    100   1/7/19 6:00   1/8/19 0:00
1/8/2019    100   1/8/19 0:00   1/9/19 0:00
1/9/2019    100   1/9/19 0:00   1/9/19 11:30
1/11/2019   100   1/11/19 12:00 1/11/19 22:00
1/13/2019   100   1/13/19 14:30 1/14/19 0:00
1/14/2019   100   1/14/19 0:00  1/15/19 0:00
1/15/2019   100   1/15/19 0:00  1/15/19 8:30
我试图将其简化为以下内容:

date    part_id   active_start    active_end
1/1/2019    100   1/1/19 8:00     1/1/19 9:30
1/1/2019    100   1/1/19 14:00    1/4/19 8:00
1/7/2019    100   1/7/19 6:00     1/9/19 11:30
1/11/2019   100   1/11/19 12:00   1/11/19 22:00
1/13/2019   100   1/13/19 14:30   1/15/19 8:30

有大约70个不同的零件号,每个零件号在观察期内有多达200个不同的活动事件。活动事件最多可以持续几天。由于我在SQL方面相当缺乏经验,因此非常感谢您的帮助。

这是一个缺口和孤岛问题,您需要将相邻行分组在一起

下面是一个使用窗口函数的解决方案:

select 
    min(date) date,
    part_id,
    min(active_start) active_start,
    max(active_end) active_end
from (
    select
        t.*,
        sum(case when lag_active_end = active_start then 0 else 1 end)
            over(partition by part_id order by active_start) grp
    from (
        select 
            t.*, 
            lag(active_end) over(partition by part_id order by active_start) lag_active_end
        from mytable t
    ) t
) t
group by part_id, grp

最内部的查询检索具有相同
part\u id
的上一条记录的结束日期。中间查询执行一个窗口和,每次前一个结束日期不等于当前开始日期时,窗口和都会增加1:这定义了相邻行的组。最后,外部查询按组聚合,并计算范围的开始和结束。

这太棒了!谢谢你的快速回复。