SELECT TOTAL_CHOGWA, CNT, USER_ID, USER_NAME, GRADE_NAME, DEFAULT_UNIT_PRICE, EXCEED_UNIT_PRICE, NVL(EXCEED_TIME,0) EXCEED_TIME, 10 DEFAULT_TIME, CASE WHEN NVL(TOTAL_TIME,0) = 0 THEN 10 ELSE NVL(TOTAL_TIME,0) END TOTAL_TIME, NVL(ACTUAL_EXCEED_TIME, 0) ACTUAL_EXCEED_TIME, (10*DEFAULT_UNIT_PRICE) DEFAULT_PRICE, NVL(TOTAL_TIME - 10,0)*EXCEED_UNIT_PRICE EXCEED_PRICE, (10*DEFAULT_UNIT_PRICE)+NVL(TOTAL_TIME - 10,0)*EXCEED_UNIT_PRICE PRICE FROM ( SELECT CHOGWA_HOUR_1 + TRUNC( CHOGWA_HOUR_2 / 60 ) || ';' || ROUND(MOD(CHOGWA_HOUR_2 / 60 , 1) * 60) TOTAL_CHOGWA , K.DEFAULT_UNIT_PRICE, K.EXCEED_UNIT_PRICE, K.OVER_TIME ACTUAL_EXCEED_TIME, CNT,
USR_SID, K.USER_NAME, K.USER_ID, K.GRADE_NAME, (CHOGWA_HOUR_1 + TRUNC( CHOGWA_HOUR_2 / 60 )) EXCEED_TIME, CASE WHEN (10+CHOGWA_HOUR_1 + TRUNC( CHOGWA_HOUR_2 / 60 )) > OVER_TIME THEN OVER_TIME ELSE 10 + CHOGWA_HOUR_1 + TRUNC( CHOGWA_HOUR_2 / 60 ) END TOTAL_TIME FROM ( SELECT SUM( SUBSTR(TO_CHAR(CHOGWA , 'HH24MI') , 1 , 2) ) CHOGWA_HOUR_1 , SUM( SUBSTR(TO_CHAR(CHOGWA , 'HH24MI') , 3 , 4) ) CHOGWA_HOUR_2 , COUNT(*) CNT, USR_SID FROM ( SELECT CASE WHEN TO_DATE('040000' , 'HH24MISS') < COMPARE_TIME THEN TO_DATE('040000' , 'HH24MISS') ELSE CASE WHEN TO_DATE('000000' , 'HH24MISS') < COMPARE_TIME THEN COMPARE_TIME ELSE TO_DATE('000000' , 'HH24MISS') END END CHOGWA, DEP_CODE, USR_SID, CLSS_NM FROM ( SELECT EXCE_WORK_YMD , WORK_ST_TM , WORK_END_TM , DEP_CODE, USR_SID, CLSS_NM , TO_DATE ( CASE WHEN ROUND( MOD(COMPARE_TIME - THIRD_TIME , 1) * 24 * 60 * 60 ) < 0 THEN 0 ELSE ROUND( MOD(COMPARE_TIME - THIRD_TIME , 1) * 24 * 60 * 60 ) END , 'SSSSS' ) COMPARE_TIME FROM ( SELECT EXCE_WORK_YMD , WORK_ST_TM , WORK_END_TM , THIRD_TIME , DEP_CODE, USR_SID, CLSS_NM , TO_DATE( ROUND( MOD(SECOND_TIME - FIRST_TIME , 1) * 24 * 60 * 60 ) , 'SSSSS') COMPARE_TIME FROM ( SELECT ( TO_CHAR(TO_DATE(EXCE_WORK_YMD , 'XYYYY-MM-DD') , 'YYYY-MM-DD') || '(' || TO_CHAR(TO_DATE(EXCE_WORK_YMD , 'YYYY-MM-DD') , 'DY' , 'NLS_DATE_LANGUAGE=KOREAN') || ')' ) EXCE_WORK_YMD , TO_CHAR(TO_DATE(WORK_ST_TM , 'HH24MISS') , 'HH24MI') WORK_ST_TM , --출근시간 CASE WHEN TO_NUMBER(WORK_END_TM) > 2359 THEN TO_CHAR(TO_DATE('2359' , 'HH24MISS') , 'HH24MI') ELSE TO_CHAR(TO_DATE(WORK_END_TM , 'HH24MISS') , 'HH24MI') END WORK_END_TM , --퇴근시간 CASE WHEN HOLIDAY_SE = 0 AND TO_NUMBER(WORK_ST_TM) > 0800 THEN TO_DATE('0900' , 'HH24MISS') ELSE TO_DATE(WORK_ST_TM , 'HH24MISS') END FIRST_TIME , --계산용 출근시간 CASE WHEN TO_NUMBER(WORK_END_TM) > 2359 THEN TO_DATE('2359' , 'HH24MISS') ELSE TO_DATE(WORK_END_TM , 'HH24MISS') END SECOND_TIME , --계산용 퇴근시간 DECODE( HOLIDAY_SE , 1 , TO_DATE('000000' , 'HH24MISS') , TO_DATE('100000' , 'HH24MISS') ) THIRD_TIME , DEP_CODE, USR_SID, CLSS_NM FROM SLFTNGOVWRK WHERE BSN_SE = '002' AND SUBSTR (EXCE_WORK_YMD, 1, 6) = '201312' ) M, (SELECT USER_SN FROM SSOV_USER WHERE DEPT_ID='30301230000') N WHERE M.USR_SID=N.USER_SN ) ) ) WHERE 1=1 GROUP BY USR_SID ) A, ( SELECT A.USER_NAME, A.DEPT_NAME, A.USER_SN, A.USER_ID, B.DEFAULT_UNIT_PRICE, B.EXCEED_UNIT_PRICE, A.GRADE_NAME, A.GRADE_ID, A.POSITION_ID, CASE WHEN A.USER_ID = C.USER_ID THEN C.OVER_TIME ELSE DECODE((SELECT 'Y' FROM DUAL WHERE EXISTS(SELECT 'Y' FROM U103_USER_OVER_TIME_DEFAULT)), 'Y', (SELECT OVER_TIME_DEFAULT FROM U103_USER_OVER_TIME_DEFAULT), 0) END OVER_TIME FROM SSOV_USER A, U103_UNIT_PRICE B, U103_USER_OVER_TIME C WHERE DEPT_ID='30301230000' AND USER_STAT IN ('AAA', 'AAB', 'BAB', 'BAF', 'BAN', 'BAP', 'DAC', 'BAR') AND USE_YN='1' AND A.GRADE_ID = B.UNIT_CLASS AND A.USER_ID = C.USER_ID(+) AND USER_SN > '3900000000000' AND A.USER_ID NOT IN (SELECT CONTRACT_WORKERS_ID FROM U103_UNIT_PRICE WHERE CONTRACT_WORKERS_DEPT_CODE = '30301230000' AND DEL_YN = 'N') AND B.REGULARITY = 'Y' UNION SELECT A.USER_NAME, A.DEPT_NAME, A.USER_SN, A.USER_ID, B.DEFAULT_UNIT_PRICE, B.EXCEED_UNIT_PRICE, A.GRADE_NAME, A.GRADE_ID, A.POSITION_ID, CASE WHEN A.USER_ID = C.USER_ID THEN C.OVER_TIME ELSE DECODE((SELECT 'Y' FROM DUAL WHERE EXISTS(SELECT 'Y' FROM U103_USER_OVER_TIME_DEFAULT)), 'Y', (SELECT OVER_TIME_DEFAULT FROM U103_USER_OVER_TIME_DEFAULT), 0) END OVER_TIME FROM SSOV_USER A, U103_UNIT_PRICE B, U103_USER_OVER_TIME C WHERE DEPT_ID='30301230000' AND USER_STAT IN ('AAA', 'AAB', 'BAB', 'BAF', 'BAN', 'BAP', 'DAC', 'BAR') AND USE_YN='1' AND A.USER_ID = B.CONTRACT_WORKERS_ID(+) AND A.USER_ID = C.USER_ID(+) AND USER_SN > '3900000000000' AND A.USER_ID IN (SELECT CONTRACT_WORKERS_ID FROM U103_UNIT_PRICE WHERE CONTRACT_WORKERS_DEPT_CODE = '30301230000' AND DEL_YN = 'N') AND B.REGULARITY = 'N' ) K WHERE A.USR_SID(+)=K.USER_SN ORDER BY GRADE_ID, POSITION_ID )
맨 안쪽의 년월 조건 변경하세요.
-- AND SUBSTR (exce_work_ymd, 1, 6) = '201312'
AND exce_work_ymd >= TO_DATE('201312', 'yyyymm')
AND exce_work_ymd < ADD_MONTHS(TO_DATE('201312', 'yyyymm'), 1)
조건 주실 때 컬럼을 변형하지 마시고 조건값을 변형하세요.
그리고 맨 안쪽 쿼리의 Case 문은 쓸데 없는 복잡한 구문인 듯 합니다.
안써도 될 TO_NUMBER, TO_DATE, TO_CHAR 를 너무 그냥 막 가져다가 쓴 느낌?
work_st_tm, work_end_tm 이 4자리 문자열이라면?
TO_NUMBER, TO_DATE, TO_CHAR 등은 모두 다 필요 없어 보입니다.
M 과 N 의 조인도
N 을 M 안으로 밀어넣어 조인하셔도 될것 같구요.
K 안쪽 쿼리의 Exists 구문은 완전 잘못 사용하신 구문이구요.
Exists 를 이런식으로 사용하시면 아무 소용 없습니다.
Exists 구문은 메인쿼리의 컬럼을 서브쿼리에 조건으로 투입시켜야 합니다.
아무 조건 없이 사용한 Exists 구문은 항상 참일 수밖에 없습니다.
K 안쪽 쿼리의 UNION 은 UNION ALL 로 써야 하구요.
NOT IN 은 아우터 조인 후 널체크 하는 방식으로 바꿀 수 있습니다.
더 나아가서는 IN, NOT IN 두개로 나누지 말고
IN 절의 서브쿼리를 FROM 절로 올려 아우터 조인 한뒤
조인 결과가 있는지 없는지에 따라 다르게 표현하는 방식으로 하면
UNION 없이 하나로 가능 할듯도 합니다.
SELECT a.user_name , a.dept_name , a.user_sn , a.user_id , NVL(b1.default_unit_price, b.default_unit_price) default_unit_price , NVL(b1.exceed_unit_price , b.exceed_unit_price ) exceed_unit_price , a.grade_name , a.grade_id , a.position_id , COALESCE( c.over_time , (SELECT over_time_default FROM u103_user_over_time_default) , 0 ) over_time FROM ssov_user a , u103_unit_price b , u103_unit_price b1 , u103_user_over_time c WHERE dept_id = '30301230000' AND user_stat IN ('AAA', 'AAB', 'BAB', 'BAF', 'BAN', 'BAP', 'DAC', 'BAR') AND use_yn = '1' AND a.user_id = c.user_id(+) AND user_sn > '3900000000000' AND b.regularity = 'Y' AND a.grade_id = b.unit_class(+) AND a.user_id = b1.contract_workers_id(+) AND b1.contract_workers_dept_code(+) = '30301230000' AND b1.del_yn(+) = 'N' ;