Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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 2008 - Fatal编程技术网

Sql 计算行之间的时间差

Sql 计算行之间的时间差,sql,sql-server-2008,Sql,Sql Server 2008,我目前有一个以下格式的数据库 ID | DateTime | PID | TIU 1 | 2013-11-18 00:15:00 | 1551 | 1005 2 | 2013-11-18 00:16:03 | 1551 | 1885 3 | 2013-11-18 00:16:30 | 9110 | 75527 4 | 2013-11-18 00:22:01 | 1022 | 75 5 | 2013-

我目前有一个以下格式的数据库

ID  |  DateTime             |  PID   |  TIU
1   |  2013-11-18 00:15:00  |  1551  |  1005
2   |  2013-11-18 00:16:03  |  1551  |  1885
3   |  2013-11-18 00:16:30  |  9110  |  75527
4   |  2013-11-18 00:22:01  |  1022  |  75
5   |  2013-11-18 00:22:09  |  1019  |  1311
6   |  2013-11-18 00:23:52  |  1022  |  89
7   |  2013-11-18 00:24:19  |  1300  |  44433
8   |  2013-11-18 00:38:57  |  9445  |  2010
我有一个场景,我需要使用
DateTime
列来确定流程中超过5分钟的差距

我正在努力实现的一个例子是:

ID  |  DateTime             |  PID   |  TIU
3   |  2013-11-18 00:16:30  |  9110  |  75527
4   |  2013-11-18 00:22:01  |  1022  |  75
7   |  2013-11-18 00:24:50  |  1300  |  44433
8   |  2013-11-18 00:38:57  |  9445  |  2010
ID3是6分1秒间隔前的最后一行,ID4是间隔后的下一行。
ID7是14分7秒间隔前的最后一行,ID8是下一条可用记录

我正试图用SQL来实现这一点,但是如果需要的话,我可以用C#to process来实现


我尝试了许多内部联接,但是该表超过300万行,因此性能受到很大影响。

这是一个CTE解决方案,但是,正如已经指出的,这可能并不总是表现良好-因为我们必须针对
DateTime
列计算函数,大多数索引都是无用的:

declare @t table (ID int not null,[DateTime] datetime not null,
                  PID int not null,TIU int not null)
insert into @t(ID,[DateTime],PID,TIU) values
(1,'2013-11-18 00:15:00',1551,1005  ),
(2,'2013-11-18 00:16:03',1551,1885  ),
(3,'2013-11-18 00:16:30',9110,75527 ),
(4,'2013-11-18 00:22:01',1022,75    ),
(5,'2013-11-18 00:22:09',1019,1311  ),
(6,'2013-11-18 00:23:52',1022,89    ),
(7,'2013-11-18 00:24:19',1300,44433 ),
(8,'2013-11-18 00:38:57',9445,2010  )

;With Islands as (
    select ID as MinID,[DateTime],ID as RecID from @t t1
    where not exists
        (select * from @t t2
            where t2.ID < t1.ID and --Or by date, if needed
                    --Use 300 seconds to avoid most transition issues
            DATEDIFF(second,t2.[DateTime],t1.[DateTime]) < 300
        )
    union all
    select i.MinID,t2.[DateTime],t2.ID
    from Islands i
        inner join
        @t t2
            on
                i.RecID < t2.ID and
                DATEDIFF(second,i.[DateTime],t2.[DateTime]) < 300
), Ends as (
    select MinID,MAX(RecID) as MaxID from Islands group by MinID
)
select * from @t t
where exists(select * from Ends e where e.MinID = t.ID or e.MaxID = t.ID)

我们所关心的是最后一行,在这一行中,我们确定了从ID 4到ID 7的时间“孤岛”——这就是第二个CTE(
结束
)为我们找到的。虽然基于集合的解决方案很可爱,并且使SQL功能强大,但这可能需要迭代解决方案。也就是说,它仍然可以在SQL中完成(可能更好)。如果你想找出这一行和下一行之间的差距,你可能要找的是一个游标和一个临时表或CTE的插入。这看起来很有希望,我唯一的问题是关于开始时的
insert-INTO
语句。有没有一种方法可以使用表中已有的数据,因为我需要检查3mil+行。@lethalMango-是的,脚本的顶部只是设置数据,以便我的答案提供一个完整的脚本,您(或任何人)可以在SSMS中运行。要使用您的表,您可以跳过顶部部分,只需将对
@t
的所有引用替换为实际表即可。
4,00:22:01,4
4,00:22:09,5
4,00:23:52,6
4,00:24:19,7