是否可以根据 start/end 日期和 oracle sql 中的暂停计算有效班次时间

Is it possible to calculate the effective shift time based on a start/end date and pauses in oracle sql

我在 Oracle

中有一个 table
shift_id timestamp_(oracle) type_
00000001 17/05/2022 08:00 0001
00000001 17/05/2022 09:00 0002
00000001 17/05/2022 09:15 0003
00000001 17/05/2022 12:00 0002
00000001 17/05/2022 13:00 0003
00000001 17/05/2022 15:00 0004

类型 1 是开始时间,类型 2 是暂停,类型 3 是暂停后继续,类型 4 是 end_time

我想计算有效班次时间,我认为一种方法是计算所有开始和结束时间的总和并减去它们,例如:

(总和(0002型)+总和(0004型))-(总和(0001型)+总和(0003型))

但是如何在 oracle 中做到这一点 sql?

我试过: select shift_id, sum(to_number_to_char(timestamp_,'sssss') where (type_ = 0002 or type is 0004) group by shift_id

然后我得到这样的结果 00000001, 82442 但是总和不是正确的总和,它只计算午夜后的秒数。

问题:如何得到如下结果: 00000001, 05:45

执行 LAG 可让您访问当前值和先前值

select 
  shift_id,
  typ,
  tstamp,
  lag(typ) over ( order by tstamp ) prev_typ,
  lag(tstamp) over ( order by tstamp ) prev_tstamp
from ...

一旦你有了它,你就可以根据需要计算间隔,例如

select 
  shift_id,
  min(case when typ = 1 then tstamp end ) start_time
  max(case when typ = 4 then tstamp end ) end_time
  sum(case when typ in (2,4) then tstamp - prev_tstamp  end ) 
from 
  ( < above > 
group by shift_id

或类似的取决于你想如何切片和切块

可以用LAGwindow函数计算时间差,然后SUM得到总金额-

CALC AS (SELECT d.*,
                EXTRACT(DAY FROM timestamp_oracle - LAG(timestamp_oracle) OVER(PARTITION BY shift_id ORDER BY timestamp_oracle)) * 24 * 60 +
                EXTRACT(HOUR FROM timestamp_oracle - LAG(timestamp_oracle) OVER(PARTITION BY shift_id ORDER BY timestamp_oracle)) * 60 +  
                EXTRACT(MINUTE FROM timestamp_oracle - LAG(timestamp_oracle) OVER(PARTITION BY shift_id ORDER BY timestamp_oracle)) tm
  FROM data d)
  SELECT shift_id,
         TRUNC(ROUND(SUM(CASE WHEN type_ <> '0003' then tm else null end))/ 60) || ':' ||
         MOD(ROUND(SUM(CASE WHEN type_ <> '0003' then tm else null end)), 60) tot_tm
    from calc
   GROUP BY shift_id;

Demo.