Oracle: Days between two date and Exclude weekdays

2020-02-02 02:42发布

问题:

I have two date columns and trying to measure days between the two dates excluding weekends. I'm getting a negative number and need help solving.

Table

CalendarDate    DayNumber  FirstAssgn    FirstCnt   DayNumber2  Id  BusinessDays
5/21/2017        Sunday       5/21/17      5/21/17    Sunday    1     -1

Query:

 TRUNC(TO_DATE(A.FIRST_CONTACT_DT, 'DD/MM/YYYY')) - TRUNC(TO_DATE(A.FIRST_ASSGN_DT, 'DD/MM/YYYY'))
 - ((((TRUNC(A.FIRST_CONTACT_DT,'D'))-(TRUNC(A.FIRST_ASSGN_DT,'D')))/7)*2) 
  - (CASE WHEN TO_CHAR(A.FIRST_ASSGN_DT,'DY','nls_date_language=english') ='SUN' THEN 1 ELSE 0 END)
- (CASE WHEN TO_CHAR(A.FIRST_CONTACT_DT,'DY','nls_date_language=english')='SAT' THEN 1 ELSE 0 END) 
- (SELECT COUNT(1) FROM HUM.CALENDAR CAL
                   WHERE 1=1
                     AND CAL.CALENDAR_DATE >= A.FIRST_ASSGN_DT
                     AND CAL.CALENDAR_DATE < A.FIRST_CONTACT_DT
                     --BETWEEN A.FIRST_ASSGN_DT AND A.FIRST_CONTACT_DT                      
                     AND CAL.GRH_HOLIDAY_IND = 'Y'
                                                  ) AS Business_Days 

Looks like below piece needs editing...

- (CASE WHEN TO_CHAR(A.FIRST_ASSGN_DT,'DY','nls_date_language=english')='SUN' THEN 1 ELSE 0 END)

回答1:

Adapted from my answer here:

Get the number of days between the Mondays of both weeks (using TRUNC( datevalue, 'IW' ) as an NLS_LANGUAGE independent method of finding the Monday of the week) then add the day of the week (Monday = 1, Tuesday = 2, etc., to a maximum of 5 to ignore weekends) for the end date and subtract the day of the week for the start date. Like this:

SELECT ( TRUNC( end_date, 'IW' ) - TRUNC( start_date, 'IW' ) ) * 5 / 7
       + LEAST( end_date - TRUNC( end_date, 'IW' ) + 1, 5 )
       - LEAST( start_date - TRUNC( start_date, 'IW' ) + 1, 5 )
          AS WeekDaysDifference
FROM   your_table


回答2:

With RANGE_TEMP as (

SELECT
    STARTPERIOD start_date,
    ENDPERIOD end_date 
FROM
    TABLE_DATA -- YOUR TABLE WITH ALL DATA DATE

), DATE_TEMP AS (

SELECT
    (start_date + LEVEL) DATE_ALL
FROM
    RANGE_TEMP
CONNECT BY LEVEL <= (end_date - start_date)

), WORK_TMP as (

SELECT
    COUNT(DATE_ALL) WORK_DATE
FROM
    DATE_TEMP
WHERE
    TO_CHAR(DATE_ALL,'D', 'NLS_DATE_LANGUAGE=ENGLISH') NOT IN ('1','7')

), BUSINESS_TMP as (

SELECT
    COUNT(DATE_ALL) BUSINESS_DATE
FROM
    DATE_TEMP
WHERE
    TO_CHAR(DATE_ALL,'D', 'NLS_DATE_LANGUAGE=ENGLISH') IN ('1','7')

) SELECT L.WORK_DATE, H.BUSINESS_DATE FROM BUSINESS_TMP H, WORK_TMP L ;