2017-04-26 7 views
0

2つの日付をキャストし、それらが等しいかどうかを調べるSQLクエリがあります。しかし、日付は同じですが、私は結果を得ることはありません。休日を除く2つの日付間の平日の数を取得する関数

create or replace 
FUNCTION getWorkingDays(
    DATE_ONE DATE, 
    DATE_TWO DATE) 
RETURN NUMBER 
IS 
DAY_COUNT NUMBER := 0; 
START_DATE DATE; 
END_DATE DATE; 
HOL_COUNT NUMBER := 0; 
BEGIN   
IF(DATE_ONE     IS NOT NULL AND DATE_TWO IS NOT NULL) THEN 
    IF DATE_ONE     < DATE_TWO THEN 
    START_DATE    := DATE_ONE; 
    END_DATE     := DATE_TWO; 
    ELSE 
    START_DATE := DATE_TWO; 
    END_DATE := DATE_ONE; 
    END IF;  
    WHILE START_DATE < END_DATE  
    LOOP  
    IF TO_CHAR(START_DATE,'DY') NOT IN ('SAT','SUN') THEN 
     DAY_COUNT := DAY_COUNT   + 1; 
    END IF;  
    SELECT count(*) INTO HOL_COUNT 
FROM ATL_JOB_HOLIDAY jh 
JOIN ATL_MASTER_JOB mj 
ON MJ.MASTER_JOB_ID  = JH.MASTER_JOB_ID 
WHERE TRUNC(HOLIDAY_DATE) = START_DATE; 
    IF(HOL_COUNT >0) THEN 
     DAY_COUNT := DAY_COUNT   + 1; 
     Dbms_Output.put_line('Holiday333 :- IS A HOLIDAY'); 
     END IF; 
     START_DATE := START_DATE + 1;  
    END LOOP; 
END IF; 
RETURN DAY_COUNT; 
EXCEPTION 
WHEN OTHERS THEN 
    RETURN NULL; 
END getWorkingDays;' 
+5

あなたのDBMSは何ですか? "in sql"?どのようなSQL?オラクル? PostgreSQL? –

+0

ANSI SQLは'16 -APR-11 'を日付として認識しません。どのdbmsを使用していますか? – jarlh

答えて

0

私はあなたがOracleを使用していると推測しています。その場合、DATEデータ型には時間コンポーネントが含まれます。これはむしろ混乱します。

SELECT TRUNC(HOLIDAY_DATE), DATE '2011-04-16' --into DAY_COUNT 
FROM ATL_JOB_HOLIDAY jh JOIN 
    ATL_MASTER_JOB mj 
    ON mj.MASTER_JOB_ID = jh.MASTER_JOB_ID 
WHERE TRUNC(HOLIDAY_DATE) = DATE '2011-04-16'; 

注意をもANSI標準の日付のと表の別名を好む:しかし、あなたは、あなたがTRUNC()ではなくCAST()を使ってやりたいことができます。

+0

これは一例です。私は問題がある元の関数を持っています – Ann

0

句は次のようであるあなたの場所:

where trunc(HOLIDAY_DATE) = to_date('2016-APR-11', 'yyyy-mon-dd') 
0

は、私はあなたの以前の質問に、このの大半を掲載しました。日をループして、それぞれを個別にチェックする必要はありません。

CREATE FUNCTION getWorkingDays (
    in_start_date IN DATE, 
    in_end_date IN DATE 
) RETURN NUMBER 
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 := TRUNC(LEAST(in_start_date, in_end_date)); 
    p_end_date := TRUNC(GREATEST(in_start_date, in_end_date)); 

    -- 5/7 * (Number of weekdays 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') + 1, 5) 
        - LEAST(p_start_date - TRUNC(p_start_date, 'IW') + 1, 5); 

    SELECT COUNT(DISTINCT TRUNC(HOLIDAY_DATE)) 
    INTO p_holiday_days 
    FROM ATL_JOB_HOLIDAY jh 
    JOIN ATL_MASTER_JOB mj 
    ON  MJ.MASTER_JOB_ID = JH.MASTER_JOB_ID 
    WHERE TRUNC(HOLIDAY_DATE) BETWEEN p_start_date AND p_end_date; 

    RETURN p_working_days - p_holiday_days; 
END; 
/

(注:あなたは週の日数を計算して、ちょうどあなたのテーブルに個別の日数を引くことができるはずHOLIDAY_DATEin_start_datein_end_dateTRUNCは、すべての時間コンポーネントように、比較する前にatedされています)実質的に無視されます。

+0

これは全体の日数をカウントします - 部分的な日を処理するには、[この回答](https://stackoverflow.com/a/44407013/1509264)でこの関数のリビジョンを参照してください。 – MT0

関連する問題