create custom function for date difference excluding weekends and holidays in oracle sql

前端 未结 1 1243
没有蜡笔的小新
没有蜡笔的小新 2020-12-04 03:47

I need to calculate the number of days between two dates as decimal, excluding the weekends and holidays by using a custom function

相关标签:
1条回答
  • 2020-12-04 04:12

    You do not need to use a row generator to enumerate every day to get the number of week days - it can be done using a simple calculation:

    From my answer here:

    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;
    /
    
    0 讨论(0)
提交回复
热议问题