2017-10-10 59 views
0

我有兩個表可供我使用,其中一個是main_table,帶有start_date和end_date,另一個是holiday_table,其中所有客戶端節假日和週末都標記了。如何計算Oracle中的營業日

我需要計算從start_date到end_date的所有工作日,消除該特定持續時間內在holiday_table中發生的所有假期。

MAIN_TABLE(開始日期日期,結束日期日期)和holiday_table(節假日日期) 我有一段代碼,其容易地分離在holiday_table列出的所有節假日,僅當起始日期日期和結束日期的值是硬編碼的。 (選擇次數(*)(日期/年月日)(日期/月/年) )from holiday_2016 t where t.holidays> to_date('10/01/2017',

'mm/dd/yyyy')and t.holidays < = to_date('10/10/2017','mm/dd/yyyy'))from dual

但是這不是我想要的,因爲我有一個表,其中有不同的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日期和結束日期:具有START_DATE <

  1. 請求'10/01/2017' 和起始日期> '10/20/2017' 將被淘汰
  2. 請求具有END_DATE < '10/01/2017' 和起始日期> '10/20/2017' 也將消除
+1

請提供樣本數據和預期結果(根據您提供的數據) –

+0

您的數據模型不清楚。假期屬性的內容是什麼?輸出結果也不清楚。 –

+0

我已經抽出了I/P和期望的O/P表以及所提到的表的屬性。讓我知道,如果它仍然不清楚。 – Sam

回答

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 

編輯我現在已經看到了一些樣本數據我不知道,如果你需要刪除週末或沒有。看來你可能非工作日明確存儲曾經在假期表,所以你可能只需要這樣:

, 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 
; 

查詢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 | 
+0

代碼工作完全正常,進行了一些必要的更改。謝謝!! – Sam

+0

'to_char(t.START_DATE,'day')='sunday''應該寫成'to_char(t.START_DATE,'fmday','nls_date_language = american')='sunday''。我想知道爲什麼'to_char(t.START_DATE,'day')='sunday'似乎沒有'fm'(或'''sunday'') –