【发布时间】:2021-07-17 14:15:13
【问题描述】:
我需要通过使用Oracle中的自定义函数将两个日期之间的天数计算为十进制,不包括周末和节假日 SQL。 网站上有类似的问题;但是,正如我所看到的,它们都没有使用自定义函数要求以十进制形式输出。我需要小数的原因是之后能够使用/提取时间分量。如果已经有这样的问题,请分享链接。
借助我在互联网上找到的附加内容thanks to the author,尝试编写如下函数。内部子查询单独工作正常,但不能作为一个整体函数工作。
简而言之,这个想法是:
(计算 startdate 和 enddate 之间的天差)->(排除 startdate 和 enddate 之间的周末天数)->(排除 startdate 和 enddate 之间的周末天数)
当我尝试保存函数时,它给出了错误PLS-00103: Encountered the symbol "end-of-file"。由于我已经是函数新手,可能缺少一些基本的东西。
最后,如果您对如何提高代码效率有任何建议,请告诉我。
提前致谢!
CREATE OR REPLACE FUNCTION NET_WORKING_DAYS (startdate IN DATE, enddate IN DATE)
RETURN NUMBER IS
WORKINGDAYS_BETWEEN NUMBER;
BEGIN
SELECT
-- number of days between startdate and enddate
(
SELECT (TO_DATE('20160831150000','YYYYMMDDHH24MISS') - TO_DATE('20160801000000','YYYYMMDDHH24MISS') ) DAYS_BETWEEN
FROM DUAL
)
-
-- number of weekend days (after a given date)
(
SELECT COUNT(1) WEEKEND_DAYS_BETWEEN
FROM
(
SELECT
TO_DATE('20160701000000','YYYYMMDDHH24MISS') + SEQ as day_date, --2016/07/01 is a constant/given date for this formula
TO_CHAR(TO_DATE('20160701000000','YYYYMMDDHH24MISS') + SEQ , 'D') day_of_week
FROM
(
SELECT ROWNUM-1 SEQ
FROM ( SELECT 1 FROM DUAL CONNECT BY LEVEL<= 365 * 5) --5 years
)
ORDER BY 1
)
WHERE day_of_week IN (6,7)
AND day_date > TO_DATE('20160801000000','YYYYMMDDHH24MISS') --this should be replaced with startdate parameter
AND day_date < TO_DATE('20160831000000','YYYYMMDDHH24MISS') --this should be replaced with enddate parameter
)
-
-- number of holidays (after a given date)
(
SELECT COUNT(1)
FROM HOLIDAYS
WHERE HOLIDAY_DATE > TO_DATE('20160801000000','YYYYMMDDHH24MISS') --this should be replaced with startdate parameter
AND HOLIDAY_DATE < TO_DATE('20160831000000','YYYYMMDDHH24MISS') --this should be replaced with enddate parameter
)
INTO WORKINGDAYS_BETWEEN
FROM DUAL;
RETURN WORKINGDAYS_BETWEEN;
END NET_WORKING_DAYS;
**EDIT-1:假期已在数据库的 HOLIDAYS 表中定义,对于此日期范围从 20160801000000 到 20160831000000 ,30.06.2016 是假期日期。
【问题讨论】:
-
对于 2016-08-26 08:16:39 到 2016-08-30 08:17:01 的范围,如何获得所需的解决方案 4.00025...天? 2016-08-27 是星期六,2016-08-28 是星期日,2016-08-30 是假期。因此,您应该在 2016-08-29 和 2016-08-26 08:16:39 到 2016-08-27 00:00:00 有 1 全天,总共 1.655 个工作日为 0.655 天。