是否可以根据 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;
我在 Oracle
中有一个 tableshift_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;