查找两个特定SQL行之间的时间差并填充新表

时间:2017-09-08 19:28:09

标签: sql-server

我有一张桌子,缩短版本如下所示。我需要找到每个ID脱机的时间。但是,如果一个ID没有联机,它应该被忽略,每个ID可以多次离线,但需要在线下线之前上线

|ID | Description | Time               |
|---|-------------|--------------------|
|1  |Offline      |'2017-09-07 12:53:02|
|---|-------------|--------------------|
|2  |Offline      |'2017-09-07 12:54:00|
|---|-------------|--------------------|
|2  |Online       |'2017-09-07 12:54:01|
|---|-------------|--------------------|
|3  |Offline      |'2017-09-07 12:54:02|
|---|-------------|--------------------|
|1  |Online       |'2017-09-07 12:55:21|
|---|-------------|--------------------|
|2  |Offline      |'2017-09-07 12:57:21|
|---|-------------|--------------------|
|2  |Online       |'2017-09-07 12:58:21|

这是我需要的结果表,顺序无关紧要(时间差可以以秒为单位)

|ID |Time Difference |
|---|----------------|
|1  |141             |
|---|----------------|
|2  |1               |
|---|----------------|
|2  |60              |

2 个答案:

答案 0 :(得分:0)

在您的数据中,在线/离线状态是交错的。这样可以轻松使用lead()

select id,
       sum(datediff(second, time, next_t)
from (select t.*,
             lead(description) over (partition by id order by time) as next_d,
             lead(time) over (partition by id order by time) as next_t
      from t
     ) t
where description = 'Offline' and next_d = 'Online';

答案 1 :(得分:0)

尝试此代码,您可以减少代码大小并改进..但循环工作正常,将(t)替换为您的表名。希望它适合你。

Select Result

table

declare @idTable table (i_idx int identity(1,1), id int)
declare @Result table (id int, Time_diff int)
CREATE  table  #Auxtable (i_idx int identity(1,1), id int, Description varchar(50), Time datetime)

insert into @idTable 
select distinct(id) from t

declare @id int
declare @idx int
declare @idx2 int
declare @count int
declare @Offline int
declare @Online int
declare @AuxCount int
declare @auxtableCount int
declare @Description varchar(50)
declare @DescriptionNext varchar(50)
declare @time datetime
declare @timenext datetime

set @idx = 1
set @idx2 = 1
set @count = (select count(*) from @idTable)

while (@idx < @count)
begin
    set @id = (select id from @idTable where i_idx = @idx)
    set @Offline = (select count(*) from t where Description = 'Offline' and id = @idx)
    set @Online = (select count(*) from t where Description = 'Online' and id = @idx)

    if(@Offline > 0 And @Online > 0)
    begin
        insert into #Auxtable select id, Description, Time from t where id = @id order by Time
        set @auxtableCount = (select count(*) from #Auxtable)

        while(@idx2 <= @auxtableCount)
        begin   
            set @Description = (select top 1 Description from #Auxtable where i_idx = @idx2)
            set @DescriptionNext = (select Description from #Auxtable  where i_idx = @idx2 + 1)
            set @time = (select time from #Auxtable where i_idx = @idx2)
            set @timenext = (select time from #Auxtable where i_idx = @idx2 + 1)

            if(@Description = 'Offline' and @DescriptionNext = 'Online')
            begin
                insert into @Result (id, Time_diff) values (@id, datediff(second, @time, @timenext))
                set @idx2 = @idx2 + 1
            end

            set @idx2 = @idx2 + 1
        end

    end
    TRUNCATE TABLE #Auxtable
    SET @idx2 = 1

    set @idx = @idx + 1
end

DROP TABLE #Auxtable

SELECT * FROM @Result