[英]Oracle SQL Time Difference in hours
我试图找到一种方法来比较两个日期的假期时间。
目前下面的查询不包括假期并返回工作时间。 我正在努力以另一种方式得到它。 只是返回开始日期和结束日期之间的假期小时数。
如果开始日期是 15-04-22 16:00 并且它是一个假期,那么查询应该只返回 b/w 16:00 - 18:00 的小时数。 (工作时间为7:00-18:00)
create table holidays_tb(
holiday_date date
);
insert into holidays_tb values (TO_DATE('15/04/2022', 'DD/MM/YYYY'));
insert into holidays_tb values (TO_DATE('18/04/2022', 'DD/MM/YYYY'));
declare
v_st_date date;
v_end_date date;
return_val number;
begin
v_st_date := TO_DATE('13/04/2022 09:55:52', 'DD/MM/YYYY HH24:MI:SS');
v_end_date := TO_DATE('19/04/2022 16:30:00', 'DD/MM/YYYY HH24:MI:SS');
with all_days as
(select trunc(v_st_date) + level - 1 as a_dt
from dual
connect by level <= 1 + (v_end_date - v_st_date)
minus
select holiday_date from holidays_tb
)
select sum (11)
into return_val
from all_days
where TO_CHAR ( a_dt , 'Dy') NOT IN ('Sat', 'Sun');
dbms_output.put_line( return_val );
end;
现在已经坚持了几个多小时:|
您可以使用以下方法获取假期小时数:
DECLARE
v_st_date date := DATE '2022-04-13' + INTERVAL '0 09:55:52' DAY TO SECOND;
v_end_date date := DATE '2022-04-19' + INTERVAL '0 16:30:00' DAY TO SECOND;
v_work_day_start INTERVAL DAY(0) TO SECOND(0) := INTERVAL '0 07:00:00' DAY TO SECOND;
v_work_day_end INTERVAL DAY(0) TO SECOND(0) := INTERVAL '0 18:00:00' DAY TO SECOND;
v_hours NUMBER := EXTRACT(HOUR FROM v_work_day_end - v_work_day_start)
+ EXTRACT(MINUTE FROM v_work_day_end - v_work_day_start)/60
+ EXTRACT(MINUTE FROM v_work_day_end - v_work_day_start)/3600;
v_holiday NUMBER;
return_val number;
BEGIN
SELECT SUM(
LEAST(holiday_date + v_work_day_end, v_end_date)
- GREATEST(holiday_date + v_work_day_start, v_st_date)
) * 24
INTO v_holiday
FROM holidays_tb
WHERE holiday_date BETWEEN TRUNC(v_st_date) AND v_end_date
AND holiday_date - TRUNC(holiday_date, 'IW') < 5;
DBMS_OUTPUT.PUT_LINE( v_holiday );
END;
/
其中,对于样本数据,输出22
。
此外,您不需要使用递归查询来获取天数,可以使用以下方法直接计算:
DECLARE
v_st_date date := DATE '2022-04-13' + INTERVAL '0 09:55:52' DAY TO SECOND;
v_end_date date := DATE '2022-04-19' + INTERVAL '0 16:30:00' DAY TO SECOND;
v_work_day_start INTERVAL DAY(0) TO SECOND(0) := INTERVAL '0 07:00:00' DAY TO SECOND;
v_work_day_end INTERVAL DAY(0) TO SECOND(0) := INTERVAL '0 18:00:00' DAY TO SECOND;
v_hours NUMBER := EXTRACT(HOUR FROM v_work_day_end - v_work_day_start)
+ EXTRACT(MINUTE FROM v_work_day_end - v_work_day_start)/60
+ EXTRACT(MINUTE FROM v_work_day_end - v_work_day_start)/3600;
v_holiday NUMBER;
return_val number;
BEGIN
SELECT SUM(
LEAST(holiday_date + v_work_day_end, v_end_date)
- GREATEST(holiday_date + v_work_day_start, v_st_date)
) * 24
INTO v_holiday
FROM holidays_tb
WHERE holiday_date BETWEEN TRUNC(v_st_date) AND v_end_date
AND holiday_date - TRUNC(holiday_date, 'IW') < 5;
return_val :=
-- Full weeks
(TRUNC(v_end_date, 'IW') - TRUNC(v_st_date, 'IW')) * 5 / 7 * v_hours
-- Full days before in start week
- LEAST(TRUNC(v_st_date) - TRUNC(v_st_date, 'IW'), 5) * v_hours
-- Part days before in start week
- CASE
WHEN v_st_date - TRUNC(v_st_date, 'IW') < 5
THEN LEAST(
GREATEST(
(v_st_date - (TRUNC(v_st_date) + v_work_day_start))* 24,
0
),
v_hours
)
ELSE 0
END
-- End full days
+ LEAST(TRUNC(v_end_date) - TRUNC(v_end_date, 'IW'), 5) * v_hours
-- End part days
+ CASE
WHEN v_end_date - TRUNC(v_end_date, 'IW') < 5
THEN LEAST(
GREATEST(
(v_end_date - (TRUNC(v_end_date) + v_work_day_start))* 24,
0
),
v_hours
)
ELSE 0
END
-- Holiday hours
- v_holiday;
DBMS_OUTPUT.PUT_LINE( return_val );
END;
/
输出: 28.5689
(3 天 33 小时,结束时减去 1.5 小时,开始时将近 3 小时)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.