根据当前行和下一行求和行

Log*_*cal 5 sql sql-server

我有以下格式的输入: 输入图像

我必须找到当前行的停止和下一行的开始之间的差异,如果差异小于25,我需要将[TimeDiff_Start_Stop]中的值相加.如果差异超过25,我不需要做总和.

如上图所示,区别

在行1的停止和行2的开始之间是13,在行2的停止和行3的开始之间是2,在行3的停止和行4的开始之间是1,在行4的停止和行5的开始之间是在第5行的
停止和第6行的开始之间是8,但是第6行的停止和第7行的开始之间的差异是37,因此只对前6行的[TimeDiff_Start_Stop]求和,从而在输出中产生第1行.

第7行的停止和第8行的开始之间的进一步差异是20,因此第7行和第8行的[TimeDiff_Start_Stop]相加,在输出中产生第2行.

要求的输出

输出图像

我该怎么做到这一点?

请在下面找到输入和输出脚本:

输入:

select 'Sample' as COL1,'1' AS COL2,1 as 'RN','2016-05-09 02:45:18.239669' AS Start,'2016-05-09 02:45:25.837316' as Stop,7 as TimeDiff_Start_Stop
union
select 'Sample' as COL1,'1' AS COL2,2 as 'RN','2016-05-09 02:45:38.809919' AS Start,'2016-05-09 02:46:59.856081' as Stop,81 as TimeDiff_Start_Stop
union
select 'Sample' as COL1,'1' AS COL2,3 as 'RN','2016-05-09 02:47:01.831128' AS Start,'2016-05-09 02:48:55.211807' as Stop,114 as TimeDiff_Start_Stop
union
select 'Sample' as COL1,'1' AS COL2,4 as 'RN','2016-05-09 02:48:56.305736' AS Start,'2016-05-09 02:50:06.107262' as Stop,70 as TimeDiff_Start_Stop
union
select 'Sample' as COL1,'1' AS COL2,5 as 'RN','2016-05-09 02:50:09.269354' AS Start,'2016-05-09 02:50:16.081159' as Stop,7 as TimeDiff_Start_Stop
union
select 'Sample' as COL1,'1' AS COL2,6 as 'RN','2016-05-09 02:50:24.819440' AS Start,'2016-05-09 02:51:04.736300' as Stop,40 as TimeDiff_Start_Stop
union
select 'Sample' as COL1,'1' AS COL2,7 as 'RN','2016-05-09 02:51:41.029165' AS Start,'2016-05-09 02:54:04.186215' as Stop,143 as TimeDiff_Start_Stop
union
select 'Sample' as COL1,'1' AS COL2,8 as 'RN','2016-05-09 02:54:24.537167' AS Start,'2016-05-09 02:55:26.926029' as Stop,62 as TimeDiff_Start_Stop
Run Code Online (Sandbox Code Playgroud)

输出:

select 'Sample' as COL1,'1' AS COL2,'2016-05-09 02:45:18.239669' AS Start,'2016-05-09 02:51:04.736300' as Stop,319 as Time
union
select 'Sample' as COL1,'1' AS COL2,'2016-05-09 02:51:41.029165' AS Start,'2016-05-09 02:55:26.926029' as Stop,205 as Time
Run Code Online (Sandbox Code Playgroud)

Max*_*rek 3

Here are 2 different approaches - for this, I created a table @t and used your sample data to populate it - thanks for proving those. Here's the table definition:

declare @t table (col1 varchar(10), col2 int, rn int, start datetime2, stop datetime2, timediff_start_stop int)
insert into @t ... (from the OP)
Run Code Online (Sandbox Code Playgroud)

Here's an approach using a CTE. First, it creates a CTE that just adds the diff (using LEAD to get the difference between current row stop/next row start) as a column.

Note the isnull statement in the CTE query gives a value of 26 to a null if there's no following row - this means the last row in the result set with get a value of 26 (> 25, so will match the criteria of a row that should be an end time in the result set).

;with tdiff (col1, col2, rn, start, stop, timediff_start_stop, diff, timediff)
as
(
select col1, col2, rn, start, stop, timediff_start_stop, isnull(datediff(ss, stop, lead(start) over (order by rn)), 26) as diff, datediff(ss, start, stop)
from @t
)
select t1.col1, t1.col2, t1.start, (select min(stop) from tdiff where stop > t1.start and diff > 25) as stop, 
    (select sum(timediff_start_stop) from tdiff where start >= t1.start and stop <= (select min(stop) from tdiff where stop > t1.start and diff > 25)) AS TIME
from tdiff t1
left join tdiff t2 on (t1.rn - 1) = t2.rn
where t1.rn = 1 or t2.diff > 25
Run Code Online (Sandbox Code Playgroud)

Next, here's a completely different solution using cursors. Cursors are inefficient and not well suited to frequently-run tasks, but I find them easy to maintain and follow as a developer, and think it may be useful for some who need to run infrequent or one-time tasks that are suitable for cursors:

declare @outputtable table (start datetime, stop datetime)
declare @curstart datetime, @curstop datetime, @curdiff int
declare @outputstart datetime

DECLARE cur CURSOR FOR   
select start, stop, datediff(ss, stop, LEAD(start) over (order by rn))
from @t
OPEN cur  

FETCH NEXT FROM cur   
INTO @curstart, @curstop, @curdiff 

WHILE @@FETCH_STATUS = 0  
BEGIN       
    if (@outputstart is null)
        set @outputstart = @curstart

    if (@curdiff > 25)
    begin
        insert into @outputtable values (@outputstart, @curstop)
        set @outputstart = null
    end

    FETCH NEXT FROM cur   
    INTO @curstart, @curstop, @curdiff
END   
CLOSE cur;  
DEALLOCATE cur;  

insert into @outputtable values (@outputstart, @curstop)

select * from @outputtable
Run Code Online (Sandbox Code Playgroud)