쿼리 질문입니다. 0 6 2,512

by 윤경호 [Oracle 기초] 쿼리 [2013.08.27 16:16:08]



안녕하세요
쿼리를 짜다보니 궁금한게 많이 있었습니다.

"근로계약갱신일"을 기준으로 하여 1년 안에 사용한 연차사용일자의 연차사용일수의 합을 구하는 것입니다.

A테이블
근로계약갱신일

B테이블
연차사용일자 , 연차사용일수

A테이블에서 B테이블을 LEFT OUTER JOIN을 했습니다.
그런데 B테이블에서 조건을 넣다보니 막히는게 있었습니다.

B테이블 조건에서
WHERE 연차사용일자 BETWEEN ADD_MONTHS(to_date(근로계약갱신일, -12),'yyyymmdd')  AND 근로계약갱신일

이런식으로 A테이블에 있는 근로계약갱신일을 가져와서 B테이블의 조건식에 넣고 싶습니다.

어떻게해야 하나요?

SELECT  
  T1.사원번호
, T1.고용일
, SFHR_팀명(T1.팀코드, #JDCSESSION_회계단위코드#)   AS 부서명
, SFMG_성명(T1.사원번호, #JDCSESSION_기관코드#) AS 성명
, T2.연차사용일수
, SFMG_연차수(T1.사원번호, #JDCSESSION_기관코드#) - T2.연차사용일수 AS 잔여연차수
, SFMG_연차수(T1.사원번호, #JDCSESSION_기관코드#) AS 총연차수
, SFHR_직위명(T1.직위코드, #JDCSESSION_회계단위코드#) AS 직위명
, to_char(ADD_MONTHS(to_date(T1.근로계약갱신일,'yyyymmdd'), -12)+1,'yyyymmdd') AS 시작일
, T1.근로계약갱신일 AS 재계약일
   FROM ( SELECT  성명
    , 사원번호
    , 팀코드
    , 고용일
    , 직위코드
    , 기관코드
    , 근로계약갱신일
  FROM TBMG_직원정보
  WHERE 퇴직일 IS NULL
  AND 팀코드    = NVL(#팀코드#, 팀코드)
  AND 직위코드 = NVL(#직위코드#, 직위코드)
  AND 성명 LIKE #성명# || '%'
  AND 사원번호 = NVL(#사원번호#, 사원번호)
  AND 기관코드 =  #기관코드#
 
    )T1
LEFT OUTER JOIN
    (SELECT TRIM(사원번호) AS 사원번호
  , SUM(연차사용일수) AS 연차사용일수
FROM   TBMG_연차관리내역
WHERE 기관코드 =  #기관코드#
   AND 연차사용일자 BETWEEN to_char(ADD_MONTHS(to_date(T1.근로계약갱신일, 'yyyymmdd'), -12),'yyyymmdd') AND to_char(T1.근로계약갱신일) 
   
   GROUP BY 사원번호) T2
ON T1.사원번호 = T2.사원번호
   ORDER BY T1.팀코드, T1.사원번호 
---------------------------------------------------------------------------------------------------------------------------------------------------------------

AND 연차사용일자 BETWEEN to_char(ADD_MONTHS(to_date(T1.근로계약갱신일, 'yyyymmdd'), -12),'yyyymmdd') AND to_char(T1.근로계약갱신일)
T1.근로계약갱신일 을 넣어봐도 부적합한 식별자라는 오류가 뜹니다.

by 아린 [2013.08.27 16:59:45]
스칼라 서브쿼리로 풀어봤습니다. 참고하세요.

SELECT 사원번호, 고용일, 부서명, 성명
     , 연차사용일수, 총연차수 - 연차사용일수 AS 잔여연차수, 총연차수
     , 직위명, 시작일, 재계약일 
  FROM (SELECT 사원번호, 고용일
             , SFHR_팀명(팀코드, #JDCSESSION_회계단위코드#) AS 부서명
             , SFMG_성명(사원번호, #JDCSESSION_기관코드#) AS 성명
             , (SELECT SUM(연차사용일수)
                  FROM TBMG_연차관리내역 B
                 WHERE 기관코드 =  #기관코드#
                   AND B.사원번호 = A.사원번호
                   AND B.연차사용일자 
                       BETWEEN TO_CHAR(ADD_MONTHS(TO_DATE(A.근로계약갱신일
                               ,'yyyymmdd'), -12),'yyyymmdd')
                           AND A.근로계약갱신일
                ) 연차사용일수
             , SFMG_연차수(사원번호, #JDCSESSION_기관코드#) AS 총연차수
             , SFHR_직위명(직위코드, #JDCSESSION_회계단위코드#) AS 직위명
             , TO_CHAR(ADD_MONTHS(TO_DATE(근로계약갱신일,'yyyymmdd')
                       , -12)+1,'yyyymmdd') AS 시작일
             , 근로계약갱신일 AS 재계약일
             , ROWNUM rn
          FROM TBMG_직원정보 A
         WHERE 퇴직일 IS NULL
           AND 팀코드    = NVL(#팀코드#, 팀코드)
           AND 직위코드 = NVL(#직위코드#, 직위코드)
           AND 성명 LIKE #성명# || '%'
           AND 사원번호 = NVL(#사원번호#, 사원번호)
           AND 기관코드 =  #기관코드#
        )

by 윤경호 [2013.08.27 18:27:56]

답변해주셔서 감사합니다.
잘해결됐습니다.
궁금한게 있는데요

ROWNUM은 한줄씩 보여주기 위해서 하신건가요?


by 아린 [2013.08.28 10:00:11]
쿼리변환으로 인해 "연차사용일수" 서브쿼리가 두번 사용될수 있어서 
ROWNUM 을 넣었고요, ALIAS "rn" 은 빼셔도 됩니다.

by 아린 [2013.08.27 17:04:32]
그리고,  LEFT OUTER JOIN 에서 사용하신 아래 SQL 은 결과가 틀리게 나올거에요.

GROUP BY 를 사원번호로 하셨는데, SELECT 절에서는 TRIM(사원번호) 해주셨네요.
GROUP BY 에도 TRIM 해주셔야됩니다.
(trim 할 필요가 없으면 빼주시는게 좋구요)

SELECT TRIM(사원번호) AS 사원번호
     , SUM(연차사용일수) AS 연차사용일수
  FROM TBMG_연차관리내역
 WHERE 기관코드 =  #기관코드#
   AND 연차사용일자 ....
 GROUP BY 사원번호           


-- 간단 예제
-- id 에 공백이 있을경우 trim 처리
-- ex) GROUP BY 에 TRIM   처리 => 2건 
--                 TRIM 미처리 => 3건   
WITH t(id) AS(
SELECT  '111' FROM dual UNION ALL
SELECT ' 111' FROM dual UNION ALL
SELECT  '222' FROM dual UNION ALL
SELECT  '222' FROM dual
)
SELECT TRIM(id) id, COUNT(*) cnt
  FROM t
 GROUP BY id 
 -- GROUP BY TRIM(id)

by DIIIN [2013.08.27 17:05:11]
색칠된 부분이 서브쿼리 안에 있네요
서브 쿼리 밖에 있는 테이블을 참조할 수 없습니다

by 윤경호 [2013.08.27 18:28:19]
조언해주셔서 감사합니다.^^
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입