首页 文章

如何计算Oracle中的工作日[重复]

提问于
浏览
0

这个问题在这里已有答案:

我有两个表可用,一个是带有start_date和end_date的main_table,另一个是holiday_table,其中标记了所有客户端假期和周末 .

我需要计算从start_date到end_date的所有工作日,从而消除holiday_table中针对该特定持续时间发生的所有假期 .

main_table(start_date date,end_date date)和holiday_table(假日日期)我有一段代码可以很容易地分开holiday_table中列出的所有假期,前提是start_date和end_date的值是硬编码的 . 代码:select(to_date('10 / 10/2017','mm / dd / yyyy') - to_date('10 / 01/2017','mm / dd / yyyy')) - (从中选择计数(*) holiday_2016 t t.holidays> to_date('10 / 01/2017',

'mm / dd / yyyy')和t.holidays <= to_date('10 / 10/2017','mm / dd / yyyy'))来自双

但这不是我想要的,因为我有一个表,其中start_date和end_date有不同的值,因此,这些值不能被硬编码 .

i/p tables : 
1. main_table
start_date  end_date
--------------------
10/01/2017  10/10/2017 
10/05/2017  10/20/2017
09/29/2017  10/05/2017

holiday_table
holidays
------------
10/01/2017 --Sunday 
10/02/2017 --Gandhi Jayanti 
10/07/2017 --Saturday 
10/08/2017 --Sunday 
10/14/2017 --Saturday 
10/15/2017 --Sunday 
10/19/2017 --Diwali

o/p table should be like :
start_date  end_date    bus_days
------------------------------------------
10/01/2017  10/10/2017    06 
10/05/2017  10/20/2017    10
09/29/2017  10/05/2017    04

如果这样做,我需要添加过滤器到start_date和end_date:

  • 将取消具有start_date <'10/01/2017'和start_date> '10/20/2017'的请求

  • 具有end_date <'10/01/2017'和start_date> '10/20/2017'的请求也将被删除

1 回答

  • 0

    这种方法过去对我有用,可以满足类似的需求

    select
          t.START_DATE
        , t.END_DATE
    
        ,  trunc(to_number(t.END_DATE - t.START_DATE)) + 1
         - trunc(to_number(t.END_DATE - t.START_DATE) / 7) * 2
         - (CASE WHEN to_char(t.START_DATE,'day') = 'sunday' THEN 1 ELSE 0 END)
         - (CASE WHEN to_char(t.END_DATE,'day') = 'saturday' THEN 1 ELSE 0 END)
         weekdays
    
        ,  trunc(to_number(t.END_DATE - t.START_DATE)) + 1
         - trunc(to_number(t.END_DATE - t.START_DATE) / 7) * 2
         - (select count(*) from holiday_table 
            where holidays between t.START_DATE and t.END_DATE)
         businessdays_A
    
        ,  trunc(to_number(t.END_DATE - t.START_DATE)) + 1
         - trunc(to_number(t.END_DATE - t.START_DATE) / 7) * 2
         - (CASE WHEN to_char(t.START_DATE,'day') = 'sunday' THEN 1 ELSE 0 END)
         - (CASE WHEN to_char(t.END_DATE,'day') = 'saturday' THEN 1 ELSE 0 END)
         - (select count(*) from holiday_table 
            where holidays between t.START_DATE and t.END_DATE)
         businessdays_B
    
    from main_table T
    

    EDIT 现在我看到了一些样本数据我不确定你是否需要删除周末 . 您可能会在假期表中明确存储非工作日,因此您可能只需要:

    ,  trunc(to_number(t.END_DATE - t.START_DATE)) + 1
         - (select count(*) from holiday_table 
            where holidays between t.START_DATE and t.END_DATE)
         businessdays_C
    

    SQL Fiddle

    CREATE TABLE MAIN_TABLE
        (START_DATE DATE, END_DATE DATE)
    ;
    
    INSERT ALL 
        INTO main_table (START_DATE, END_DATE)
             VALUES (TO_DATE('01-Oct-2017','dd-mon-yyyy'), TO_DATE('10-Oct-2017','dd-mon-yyyy'))
        INTO main_table (START_DATE, END_DATE)
             VALUES (TO_DATE('05-Oct-2017','dd-mon-yyyy'), TO_DATE('20-Oct-2017','dd-mon-yyyy'))
        INTO main_table (START_DATE, END_DATE)
             VALUES (TO_DATE('29-Sep-2017','dd-mon-yyyy'), TO_DATE('05-Oct-2017','dd-mon-yyyy'))
    SELECT * FROM dual
    ;
    
    CREATE TABLE HOLIDAY_TABLE
        (HOLIDAYS DATE, NAME varchar2(14))
    ;
    
    INSERT ALL 
        INTO holiday_table (HOLIDAYS, NAME)
             VALUES (TO_DATE('01-Oct-2017','dd-mon-yyyy'), 'Sunday')
        INTO holiday_table (HOLIDAYS, NAME)
             VALUES (TO_DATE('02-Oct-2017','dd-mon-yyyy'), 'Gandhi Jayanti')
        INTO holiday_table (HOLIDAYS, NAME)
             VALUES (TO_DATE('07-Oct-2017','dd-mon-yyyy'), 'Saturday')
        INTO holiday_table (HOLIDAYS, NAME)
             VALUES (TO_DATE('08-Oct-2017','dd-mon-yyyy'), 'Sunday')
        INTO holiday_table (HOLIDAYS, NAME)
             VALUES (TO_DATE('14-Oct-2017','dd-mon-yyyy'), 'Saturday')
        INTO holiday_table (HOLIDAYS, NAME)
             VALUES (TO_DATE('15-Oct-2017','dd-mon-yyyy'), 'Sunday')
        INTO holiday_table (HOLIDAYS, NAME)
             VALUES (TO_DATE('19-Oct-2017','dd-mon-yyyy'), 'Diwali')
    SELECT * FROM dual
    ;
    

    Query 1

    select
          t.START_DATE
        , t.END_DATE
    
        ,  trunc(to_number(t.END_DATE - t.START_DATE)) + 1
         - trunc(to_number(t.END_DATE - t.START_DATE) / 7) * 2
         - (CASE WHEN to_char(t.START_DATE,'day') = 'sunday' THEN 1 ELSE 0 END)
         - (CASE WHEN to_char(t.END_DATE,'day') = 'saturday' THEN 1 ELSE 0 END)
         weekdays
    
        ,  trunc(to_number(t.END_DATE - t.START_DATE)) + 1
         - trunc(to_number(t.END_DATE - t.START_DATE) / 7) * 2
         - (select count(*) from holiday_table 
            where holidays between t.START_DATE and t.END_DATE)
         businessdays_A
    
        ,  trunc(to_number(t.END_DATE - t.START_DATE)) + 1
         - trunc(to_number(t.END_DATE - t.START_DATE) / 7) * 2
         - (CASE WHEN to_char(t.START_DATE,'day') = 'sunday' THEN 1 ELSE 0 END)
         - (CASE WHEN to_char(t.END_DATE,'day') = 'saturday' THEN 1 ELSE 0 END)
         - (select count(*) from holiday_table 
            where holidays between t.START_DATE and t.END_DATE)
         businessdays_B
    
            ,  trunc(to_number(t.END_DATE - t.START_DATE)) + 1
             - (select count(*) from holiday_table 
                where holidays between t.START_DATE and t.END_DATE)
             businessdays_C
    
    from main_table T
    

    Results

    |           START_DATE |             END_DATE | WEEKDAYS | BUSINESSDAYS_A | BUSINESSDAYS_B | BUSINESSDAYS_C |
    |----------------------|----------------------|----------|----------------|----------------|----------------|
    | 2017-10-01T00:00:00Z | 2017-10-10T00:00:00Z |        8 |              4 |              4 |              6 |
    | 2017-10-05T00:00:00Z | 2017-10-20T00:00:00Z |       12 |              7 |              7 |             11 |
    | 2017-09-29T00:00:00Z | 2017-10-05T00:00:00Z |        7 |              5 |              5 |              5 |
    

相关问题