Oracle
 sql >> Base de données >  >> RDS >> Oracle

ajouter des jours ouvrables dans oracle sql

Vous pouvez essayer ceci :

select max(date_field_two) as date_field_two
  from
 (
 select date'2018-08-30'+  
    cast(case when to_char(date'2018-08-30'+level,'D','NLS_DATE_LANGUAGE=ENGLISH') 
                                              in ('6','7') then 
            0
          else
            level
          end as int) as date_field_two, 
 sum(cast(case when to_char(date'2018-08-30'+level,'D','NLS_DATE_LANGUAGE=ENGLISH')  
                                               in ('6','7') then 
            0
          else
            1
          end as int)) over (order by level) as next_day
      from dual
    connect by level <= 20*1.5 
-- 20 is the day to be added, every time 5(#of business days)*1.5 > 7(#of week days)
-- 7=5+2<5+(5/2)=5*(1+1/2)=5*1.5 [where 1.5 is just a coefficient might be replaced a greater one like 2]
-- so 4*5*1.5=20*1.5 > 4*7 
  )    
 where next_day = 20;

 DATE_FIELD_TWO
-----------------
   27.09.2018

en utilisant connect by dual clause.

PS Ignoré le cas des jours fériés, qui diffèrent d'une culture à l'autre, selon que la question n'est liée qu'aux week-ends.

Démo Rextester

Modifier : Supposons que vous ayez des jours fériés le '2018-09-25' et le '2018-09-26' (dans cet ensemble de jours), alors considérez ce qui suit :

select max(date_field_two) as date_field_two
  from
 (
 select date'2018-08-30'+  
        (case when to_char(date'2018-08-30'+level,'D','NLS_DATE_LANGUAGE=ENGLISH') 
                                              in ('6','7') then 
               0
              when date'2018-08-30'+level in (date'2018-09-25',date'2018-09-26') then
               0
              else
               level
              end) as date_field_two, 
 sum(cast(case when to_char(date'2018-08-30'+level,'D','NLS_DATE_LANGUAGE=ENGLISH')  
                                               in ('6','7') then 
                0
               when date'2018-08-30'+level in (date'2018-09-25',date'2018-09-26') then
                0 
               else
                1
               end as int)) over (order by level) as next_day
      from dual
    connect by level <= 20*2 
  )    
 where next_day = 20;

 DATE_FIELD_TWO
-----------------
   01.10.2018

qui itère un jour suivant, comme dans ce cas, à moins que ce jour férié ne coïncide avec le week-end.