oracle sql组(按更改时间从有效到有效)

oracle sql组(按更改时间从有效到有效),sql,oracle,group-by,row-number,Sql,Oracle,Group By,Row Number,我有以下关于票证状态随时间变化的历史数据,我感兴趣的是VALFROM-VALTO的结果 源数据 ticket_ID, change-time , queue -------------------------------------- 001 , 2018-01-01 00:00:00, queue1 001 , 2018-01-01 00:01:00, queue1 001 , 2018-01-01 00:03:00, queue2 001

我有以下关于票证状态随时间变化的历史数据,我感兴趣的是VALFROM-VALTO的结果

源数据

ticket_ID, change-time        , queue
--------------------------------------
001      , 2018-01-01 00:00:00, queue1
001      , 2018-01-01 00:01:00, queue1
001      , 2018-01-01 00:03:00, queue2
001      , 2018-01-01 00:04:00, queue1
001      , 2018-01-01 00:05:00, queue3
目标数据

ticket_ID, valfrom            , valto              , queue
-----------------------------------------------------------
001      , 2018-01-01 00:00:00, 2018-01-01 00:02:59, queue1
001      , 2018-01-01 00:03:00, 2018-01-01 00:03:59, queue2
001      , 2018-01-01 00:04:00, 2018-01-01 00:04:59, queue1
001      , 2018-01-01 00:05:00, 2999-12-31 23:59:59, queue3
我认为这可以通过使用带有OVER的行数函数来实现。
任何有用的建议都是非常受欢迎的。

使用行号差异方法,根据连续队列值相同的情况将行划分为组,从而从下一行获取值。此后,它是一个分组操作,以获取往返时间

select ticketid,queue,min(change_time),
coalesce(max(next_change_time)-interval '1' second,timestamp '2999-12-31 23:59:59')
from (select t.*,row_number() over(partition by ticketid order by change_time) 
                 -row_number() over(partition by ticketid,queue order by change_time) as grp,
      lead(change_time) over(partition by ticketid order by changetime) as next_change_time
      from tbl t 
     ) t
group by ticketid,queue,grp

您可以通过各种方式来实现,这里我使用lag来消除行,其中先前的更改时间与当前相同,并使用lead将下一个值显示为valto:


寻找缺口和岛屿
select id, queue, ct valfrom, 
       nvl(lead(ct) over (order by ct) - interval '1' second, 
           date '3000-01-01' - interval '1' second) valto
  from (select id, ct, queue, lag(queue) over (order by ct) lq from source)
  where lq is null or lq <> queue