2017-04-12 102 views
0

我有一张表,其中包含移动设备上用户工作状态的信息。每当他们的状态发生变化时,就会创建一个新的行,并在更改之前创建它们的原始状态,以及他们现在的新状态。该表是这样的:SQL计算包含特定值的两行之间的时间差

ID  Date_Time    User  OriginalStatus  NewStatus  
--------------------------------------------------------------------------- 
60713 2017-04-11 12:14:42 Helen  Not Started  Active 
60714 2017-04-11 12:19:20 Monica Active    Paused 
60715 2017-04-11 12:20:43 Dave  Active    Paused 
60716 2017-04-11 12:32:18 Helen  Finished   Archived 
60717 2017-04-11 12:48:57 Monica Paused    Active 
60718 2017-04-11 12:52:35 Dave  Paused    Active 

我所试图做的是计算每个用户保留在每个日期上的“暂停”状态的持续时间......他们只允许从“暂停”移回到表示其“暂停”时间结束的“有效”,并且所有其他行可以被忽略,并且从“暂停”返回到“有效”的变化将不会在连续行中。

在上面的例子中,Monica在29分37秒内(12:19:20到12:48:57)一直保持“已暂停”,而Dave已被暂停31分52秒(12: 20:43至12:52:35)。

理想情况下,我想类似的结果:

User  Paused_Start_Time  Paused_End_Time  Paused_Duration 
--------------------------------------------------------------------------- 
Monica 2017-04-11 12:19:20 2017-04-11 12:48:57 00:29:37 
Dave  2017-04-11 12:20:43 2017-04-11 12:52:35 00:31:52 

我在一个损失如何去工作了这一点,因此所有的帮助感激地接受。我使用的是SQL Server 2012的

+0

特别针对SQL问题,最好提及您正在使用的DBMS版本。 – niksofteng

回答

1

我想你只需要lead()

select user, date_time as paused_starttime, next_date_time as paused_endtime 
from (select t.*, 
      lead(date_time) over (partition by user order by date_time) as next_date_time 
     from t 
    ) t 
where status = 'paused'; 

为了让你可以减去值的持续时间。但是,这将返回间隔作为datetime值。您可以将其转换为time,但时间永远不会超过24小时。当时间超过这个时间时,我不确定你想要做什么。

+0

不知道这一点。谢谢。从2012年起。 – niksofteng

+0

嗨,对不起,在回复中迟了... –

+0

嗨,对不起,在延迟回复... LEAD()会工作,但不幸的是,往往有额外的行之间的'暂停'状态和'活跃'状态。我需要的是,在发生“已暂停”的情况下,下一行与“活动”相关的用户被标识为“paused_endtime”,这是我无法弄清楚的部分,因为此行可能是多个或多个行进一步向下。 –

相关问题