[SQL] 날짜 차이가 오라클 SQL에서 주말과 휴일을 제외하고 사용자 정의 함수를 만들
SQL날짜 차이가 오라클 SQL에서 주말과 휴일을 제외하고 사용자 정의 함수를 만들
나는 오라클 SQL에서 사용자 지정 기능을 사용하여 주말 및 공휴일 제외 진수로 두 날짜 사이의 일 수를 계산해야합니다. 사이트에 비슷한 질문이 있습니다; 내가 볼 수 그러나 그들 중 누구도 사용자 정의 기능을 사용하여 진수로 출력을 요구하지 않습니다. 나는 진수를 필요로하는 이유는 나중에 사용 / 추출 시간 구성 요소 수있을 것입니다. 질문과 같이 이미 존재하는 경우, 단지 링크를 공유하시기 바랍니다.
나는 저자에 인터넷 덕분에있는 추가 콘텐츠의 도움으로 다음과 같은 함수를 작성했습니다. 내부 하위 쿼리는 별도로 잘 작동하지만, 전체 기능으로 작동하지 않습니다.
간단히, 아이디어는 다음과 같습니다
(STARTDATE 및 ENDDATE 사이 주말의 수를 제외)> - - (STARTDATE 및 ENDDATE 사이의 일의 차이를 계산)> (STARTDATE 및 ENDDATE 사이 주말의 수를 제외)
기호 "파일 끝을"가 발생했습니다 : 나는 기능을 저장하려고하면 오류 PLS-00103이 있습니다. 나는 기능에 이미 새로운 오전 때문에 아마 기본적인 뭔가가.
마지막으로, 또한 당신이 코드를보다 효율적으로하는 방법에 대한 제안이 있으면 알려 주시기 바랍니다.
사전에 감사합니다!
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;
** 편집-1 : 휴일이 이미 2016년 6월 30일는 휴가 날짜입니다, 20,160,801,000,000에서 20,160,831,000,000에 데이터베이스에서이 날짜 범위 휴일 테이블에 정의되어 있습니다.
해결법
-
==============================
1.당신은 주 일 수를 얻기 위해 매일 열거 할 행 생성기를 사용할 필요가 없습니다 - 그것은 간단한 계산을 사용하여 수행 할 수 있습니다 :
당신은 주 일 수를 얻기 위해 매일 열거 할 행 생성기를 사용할 필요가 없습니다 - 그것은 간단한 계산을 사용하여 수행 할 수 있습니다 :
여기에 내 대답에서 :
CREATE FUNCTION getWorkingDays ( in_start_date IN DATE, in_end_date IN DATE ) RETURN NUMBER DETERMINISTIC IS p_start_date DATE; p_end_date DATE; p_working_days NUMBER; p_holiday_days NUMBER; BEGIN IF in_start_date IS NULL OR in_end_date IS NULL THEN RETURN NUll; END IF; p_start_date := LEAST( in_start_date, in_end_date ); p_end_date := GREATEST( in_start_date, in_end_date ); -- 5/7 * ( Number of days between monday of the week containing the start date -- and monday of the week containing the end date ) -- + LEAST( day of week for end date, 5 ) -- - LEAST( day of week for start date, 5 ) p_working_days := ( TRUNC( p_end_date, 'IW' ) - TRUNC( p_start_date, 'IW' ) ) * 5 / 7 + LEAST( p_end_date - TRUNC( p_end_date, 'IW' ), 5 ) - LEAST( p_start_date - TRUNC( p_start_date, 'IW' ), 5 ); SELECT COALESCE( SUM( LEAST( p_end_date, holiday_date + INTERVAL '1' DAY ) - GREATEST( p_start_date, holiday_date ) ), 0 ) INTO p_holiday_days FROM Holidays WHERE HOLIDAY_DATE BETWEEN TRUNC( p_start_date ) AND TRUNC( p_end_date ) AND HOLIDAY_DATE - TRUNC( HOLIDAY_DATE, 'IW' ) < 5; RETURN GREATEST( p_working_days - p_holiday_days, 0 ); END; /
from https://stackoverflow.com/questions/44406680/create-custom-function-for-date-difference-excluding-weekends-and-holidays-in-or by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] Access 쿼리에서 시작 날짜와 종료 날짜를 사용하여 (0) | 2020.06.19 |
---|---|
[SQL] IOS : 이상의 원인을 조기 메모리 해제 번만 sqlite가 동일한 매개 변수를 사용하여 (0) | 2020.06.19 |
[SQL] 내부 쿼리에 ORDER BY주는 ORA-00907 오른쪽 괄호 누락 (0) | 2020.06.19 |
[SQL] ORA - 내부와 00,933 혼란 "로"가입 (0) | 2020.06.19 |
[SQL] 액세스에서 여러 필드 및 수출에 피벗 (0) | 2020.06.19 |