无法将表格与其自身进行比较以获取经过的时间

时间:2019-02-14 18:55:24

标签: sql sql-server

我有一张看起来像下面的表:

incidentID           timestamp             lognumber     code
265             2019-02-09 22:02:55         21452666    Active   
265             2019-02-09 22:11:12         21452677    Cleared   
277             2019-02-09 22:20:11         21453151    Active   
277             2019-02-09 22:21:15         21453160    Cleared   
307             2019-02-09 22:52:45         21453992    Active   
307             2019-02-09 23:05:06         21453997    Canceled   
307             2019-02-09 23:08:02         21453998    Active   
307             2019-02-09 23:08:05         21454002    Cleared   

logID中的每个条目都是唯一值,并且是连续的。

我想将该表与其自身进行比较,以使其看起来如下所示,这将使我能够获取活动时间戳和已解决时间戳之间的时间。

incidentID       active_timestamp          resolved_timestamp        active_code    resolved_code
265             2019-02-09 22:02:55         2019-02-09 22:11:12         Active      Cleared   
277             2019-02-09 22:20:11         2019-02-09 22:21:15         Active      Cleared   
307             2019-02-09 22:52:45         2019-02-09 23:05:06         Active      Canceled   
307             2019-02-09 23:08:02         2019-02-09 23:08:05         Active      Cleared   

当前,我正在对活动表WHERE代码=“活动”和已解决表WHERE(代码=“已清除”或代码=“已取消”)之间的eventID执行INNER JOIN,ORDER BY事件ID。但是,结果表如下所示:

incidentID        active_timestamp      resolved_timestamp  active_code resolved_code
265             2019-02-09 22:02:55     2019-02-09 22:11:12     Active      Cleared   
277             2019-02-09 22:20:11     2019-02-09 22:21:15     Active      Cleared   
307             2019-02-09 22:52:45     2019-02-09 23:05:06     Active      Canceled  
307             2019-02-09 22:52:45     2019-02-09 23:08:05     Active      Cleared 
307             2019-02-09 23:08:02     2019-02-09 23:05:06     Active      Canceled
307             2019-02-09 23:08:02     2019-02-09 23:08:05     Active      Cleared

如您所见,联接表无法正确处理具有多个活动/清除代码的事故ID。

我如何将该表与其自身连接起来,使其看起来像上面的中间表?

5 个答案:

答案 0 :(得分:0)

使用条件聚合

 select incidentID, max(case when code='Active' then timestamp end) as active_timestamp
        max(case when code='Cleared' then timestamp end) as resolved_timestamp
        from table
group by   incidentID

答案 1 :(得分:0)

select *    
from
(select * from table) x,
(select * from table) y
where   x.code = 'Active'
and x.incidentID = y.incidentID
and x.timestamp <> y.timestamp

希望有帮助! table是同一张桌子

PS:对不起,未经测试!

答案 2 :(得分:0)

有很多方法可以执行此操作,您可以使用CTE

With c as(
Select incidentID
      ,max(timestamp) as active_timestamp
From Table 
Where code like 'Active'
Group by incidentID
), d as(
Select incidentID
      ,max(timestamp) as closed_timestamp
From Table
Where code in ('Cleared','Canceled')
Group by incidentID
)
Select incidentID
     , active_timestamp
     , resolved_timestamp 
From c LEFT JOIN d ON (c.incidentID = d.incidentID)

如果您发现这样的问题,请尝试分而治之,而不是尝试通过一个查询来做所有事情

此外,这可以通过子查询或旋转表来解决。

答案 3 :(得分:0)

当我第一次查看您的问题时,我认为这很容易-自我加入将起作用。 但是很快我注意到incidentID = 307应该输出两行。

307 first_active_timestamp cancel_timestamp
307 second_active_timestamp clear_timestamp

自我加入需要一些改善...

select a.id
     , a.timestamp
     , isnull(ca.timestamp,cl.timestamp)
     , a.code
     , isnull(ca.code,cl.code) 
from (select * from incident where code='active') a
left join (select * from incident where code='cleared') cl
on (a.id=cl.id and a.lognumber < cl.lognumber)
left join (select * from incident where code='canceled') ca
on (a.id=ca.id and a.lognumber < ca.lognumber)

答案 4 :(得分:0)

这会将您的数据分为几列。然后通过事件ID查找最早的[活动]时间和最新的[清除]时间。然后在几分钟内得到差异。 (这会将Cancelled事件与事件保持在同一行)

With cte As
(
   Select 
      incidentid,
      Case When code = 'Active' Then [timestamp] End As Active,
      Case When code = 'Cleared' Then [timestamp] End As Cleared,
      Case When code = 'Canceled' Then [timestamp] End As Canceled
   From #tbl
)
Select 
   Incidentid,
   Min(Active) As Active,
   Max(Cleared) As Cleared,
   Max(Canceled) As Canceled,
   DateDiff(MINUTE,Min(Active),Max(Canceled)) As cancel_tLapse,
   DateDiff(MINUTE,Min(Active),Max(Cleared)) As tLapse
From cte
Group by incidentID

结果:

Incidentid      Active                      Cleared                     Canceled                cancel_tLapse   tLapse
265             2019-02-09  22:02:55.000    2019-02-09  22:11:12.000    NULL                    NULL            9
277             2019-02-09  22:20:11.000    2019-02-09  22:21:15.000    NULL                    NULL            1
307             2019-02-09  22:52:45.000    2019-02-09  23:08:05.000    2019-02-09 23:05:06.000 13              16