Oracle查询排除周末,以及从6PM到9PM [英] Oracle query to Exclude weekends, and 6PM to 9PM
本文介绍了Oracle查询排除周末,以及从6PM到9PM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试实现一个查询,该查询返回两个日期之间的时差(不包括周末(周六和周日))和不包括时间(下午6点至上午9点).目前,我有一个排除周末的功能,但是我无法从查询中排除时间.有人能帮忙吗?我需要帮助的文章是
I am trying to achieve a query that returns the time difference between two dates excluding weekends(Saturday and Sunday) and excluding time (6 pm-9 am). For now, I have a function that is excluding the weekends, But I am unable to exclude time from the query. Can anyone help with this? The article from which I take help is this
CREATE OR REPLACE FUNCTION get_bus_minutes_between(
p_start_date DATE,
p_end_date DATE
)
RETURN NUMBER
DETERMINISTIC -- ***** Can't hurt
IS
days_diff NUMBER := 0;
end_date DATE := p_end_date;
minutes_diff NUMBER;
start_date DATE := p_start_date;
weeks_diff NUMBER;
BEGIN
IF start_date <= end_date
THEN
-- Move start_date and end_date away from weekends
IF start_date > TRUNC (start_date, 'IW') + 5
THEN -- Use next Monday for start_date
start_date := TRUNC (start_date, 'IW') + 7;
END IF;
IF end_date > TRUNC (end_date, 'IW') + 5
THEN -- Use Friday quitting time
end_date := TRUNC (end_date, 'IW') + 4 + (16.5 / 24);
END IF;
-- Move start_date into the same weeek as end_date
-- (Remember how many weeks we had to move it)
weeks_diff := ( TRUNC (end_date, 'IW')
- TRUNC (start_date, 'IW')
) / 7;
IF weeks_diff > 0
THEN
start_date := start_date + (7 * weeks_diff);
END IF;
-- Make start_date the same day as end_date
-- (Remember how many days we had to move it)
days_diff := TRUNC (end_date) - TRUNC (start_date);
IF days_diff > 0
THEN
start_date := start_date + days_diff;
END IF;
-- Move start_date up to starting time
start_date := GREATEST ( start_date
, TRUNC (start_date) + (8.75 / 24)
);
-- Move end_date back to quitting time
end_date := LEAST ( end_date
, TRUNC (end_date) + ( CASE
WHEN TO_CHAR ( end_date
, 'DY'
, 'NLS_DATE_LANGUAGE=ENGLISH'
) = 'FRI'
THEN 16.5
ELSE 17
END
/ 24
)
);
minutes_diff := ( GREATEST ( 0
, end_date - start_date
)
* 24 * 60
)
+ (days_diff * 495) -- 495 minutes per full day (Mon.-Thu.)
+ (weeks_diff * 2445); -- 2445 minutes per full week
ELSIF start_date > end_date
THEN
minutes_diff := -get_bus_minutes_between (end_date, start_date);
ELSE -- One of the arguments was NULL
minutes_diff := NULL;
END IF;
RETURN ROUND(minutes_diff);
END get_bus_minutes_between;
推荐答案
您可以直接计算天数差异(改编自我的回答这里):
You can directly calculate the difference in days (adapted from my answer here):
SELECT start_date,
end_date,
ROUND(
(
-- Calculate the full weeks difference from the start of ISO weeks.
( TRUNC( end_date, 'IW' ) - TRUNC( start_date, 'IW' ) ) * (9/24) * (5/7)
-- Add the full days for the final week.
+ LEAST( TRUNC( end_date ) - TRUNC( end_date, 'IW' ), 5 ) * (9/24)
-- Subtract the full days from the days of the week before the start date.
- LEAST( TRUNC( start_date ) - TRUNC( start_date, 'IW' ), 5 ) * (9/24)
-- Add the hours of the final day
+ LEAST( GREATEST( end_date - TRUNC( end_date ) - 9/24, 0 ), 9/24 )
-- Subtract the hours of the day before the range starts.
- LEAST( GREATEST( start_date - TRUNC( start_date ) - 9/24, 0 ), 9/24 )
)
-- Multiply to give minutes rather than fractions of full days.
* 24 * 60
) AS work_day_mins_diff
FROM table_name;
其中的示例数据:
CREATE TABLE table_name ( start_date, end_date ) AS
SELECT DATE '2020-12-30' + INTERVAL '00' HOUR, DATE '2020-12-30' + INTERVAL '12' HOUR FROM DUAL UNION ALL
SELECT DATE '2020-12-30' + INTERVAL '18' HOUR, DATE '2020-12-30' + INTERVAL '20' HOUR FROM DUAL UNION ALL
SELECT DATE '2020-12-30' + INTERVAL '17:30' HOUR TO MINUTE, DATE '2020-12-30' + INTERVAL '21:30' HOUR TO MINUTE FROM DUAL UNION ALL
SELECT DATE '2021-01-01' + INTERVAL '00' HOUR, DATE '2021-01-04' + INTERVAL '00' HOUR FROM DUAL UNION ALL
SELECT DATE '2021-01-02' + INTERVAL '00' HOUR, DATE '2021-01-04' + INTERVAL '00' HOUR FROM DUAL UNION ALL
SELECT DATE '2020-12-28' + INTERVAL '00' HOUR, DATE '2021-01-04' + INTERVAL '00' HOUR FROM DUAL UNION ALL
SELECT DATE '2020-12-28' + INTERVAL '00' HOUR, DATE '2020-12-29' + INTERVAL '00' HOUR FROM DUAL;
输出:
(使用 ALTER SESSION SET NLS_DATE_FORMAT ='YYYY-MM-DD HH24:MI:SS(DY)';
)
START_DATE | END_DATE | WORK_DAY_MINS_DIFF
:------------------------ | :------------------------ | -----------------:
2020-12-30 00:00:00 (WED) | 2020-12-30 12:00:00 (WED) | 180
2020-12-30 18:00:00 (WED) | 2020-12-30 20:00:00 (WED) | 0
2020-12-30 17:30:00 (WED) | 2020-12-30 21:30:00 (WED) | 30
2021-01-01 00:00:00 (FRI) | 2021-01-04 00:00:00 (MON) | 540
2021-01-02 00:00:00 (SAT) | 2021-01-04 00:00:00 (MON) | 0
2020-12-28 00:00:00 (MON) | 2021-01-04 00:00:00 (MON) | 2700
2020-12-28 00:00:00 (MON) | 2020-12-29 00:00:00 (TUE) | 540
db<>小提琴此处
这篇关于Oracle查询排除周末,以及从6PM到9PM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文