Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.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/7/sql-server/26.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_Sql Server - Fatal编程技术网

Sql 基于时间值折叠多行

Sql 基于时间值折叠多行,sql,sql-server,Sql,Sql Server,我正在尝试将同一天内具有连续时间线的行折叠为一行,但由于时间间隔而出现问题。例如,我的数据集如下所示 Date StartTime EndTime ID 2017-12-1 09:00:00 11:00:00 12345 2017-12-1 11:00:00 13:00:00 12345 2018-09-08 09:00:00 10:00:00 78465 2018-09-0

我正在尝试将同一天内具有连续时间线的行折叠为一行,但由于时间间隔而出现问题。例如,我的数据集如下所示

Date            StartTime     EndTime      ID
2017-12-1       09:00:00      11:00:00    12345
2017-12-1       11:00:00      13:00:00    12345
2018-09-08      09:00:00      10:00:00    78465
2018-09-08      10:00:00      12:00:00    78465
2018-09-08      15:00:00      16:00:00    78465
2018-09-08      16:00:00      18:00:00    78465

正如up所看到的,前两行可以合并在一起,没有任何问题,因为当天没有时间间隔。然而。对于2019-09-08的参赛作品,12:00和15:00之间存在差距。我想把这四条记录合并成两行,如下所示:

Date            StartTime     EndTime      ID
2017-12-1       09:00:00      13:00:00    12345
2018-09-08      09:00:00      12:00:00    78465
2018-09-08      15:00:00      18:00:00    78465

换句话说,我只想在同一天内相同ID的时间变量连续时折叠行


谁能帮我一下吗?我尝试使用滞后和超前函数生成唯一的组,但没有成功。

您可以使用递归cte。如果结束时间与下一个开始时间相同,则将其分组为同一组。然后找到
MIN()
MAX()


除非您特别反对折叠非连续行(对于该ID而言,这些行是连续的),否则您可以使用
分组方式

SELECT
    Date,
    StartTime = MIN(StartTime),
    EndTime = MAX(EndTime),
    ID
FROM table
GROUP BY ID, Date
否则,您可以使用基于
行数的解决方案:

SELECT
    Date,
    StartTime,
    EndTime,
    ID
FROM (
    SELECT *,
        rn = ROW_NUMBER() OVER (PARTITION BY Date, ID ORDER BY StartTime)
    FROM table
) t
WHERE rn = 1

这是一个缺口和孤岛问题的例子——实际上是一个非常简单的例子。其思想是为每一行指定一个“孤岛”分组,指定它们应该合并,因为它们重叠。然后加总

你如何分配这个岛?在这种情况下,请查看前面的
结束时间
,如果它与
开始时间
不同,则该行将启动一个新孤岛。瞧!开始标志的累积和标识每个岛

作为SQL:

select id, date, min(starttime), max(endtime)
from (select t.*,
             sum(case when prev_endtime = starttime then 0 else 1 end) over (partition by id, date order by starttime) as grp
      from (select t.*,
                   lag(endtime) over (partition by id, date order by starttime) as prev_endtime
            from t
           ) t
     ) t
group by id, date, grp;
他是一把小提琴

注意:这假设时间段不会跨越多天。该代码可以很容易地修改,以处理。但是有一个警告。开始时间和结束时间应存储为
datetime
(或相关的时间戳),而不是将日期和时间分隔为不同的列。为什么?SQL Server不支持将
'24:00:00'
作为有效时间

select id, date, min(starttime), max(endtime)
from (select t.*,
             sum(case when prev_endtime = starttime then 0 else 1 end) over (partition by id, date order by starttime) as grp
      from (select t.*,
                   lag(endtime) over (partition by id, date order by starttime) as prev_endtime
            from t
           ) t
     ) t
group by id, date, grp;