Oracle/SQL2014. 4. 17. 23:52

최종 변경 이력을 조회해보자.


예제를 위해 아래와 같이 테이블을 생성하자.

-- 1
DROP TABLE t1 PURGE;

CREATE TABLE t1 (
    ym    VARCHAR2(6) -- 연월
  , bf_cd VARCHAR2(4) -- 변경전코드
  , af_cd VARCHAR2(4) -- 변경후코드
  , CONSTRAINT t1_pk PRIMARY KEY (bf_cd)
)
ORGANIZATION INDEX;

INSERT INTO t1 VALUES ('201401', 'A', 'B'); -- 201401에 A 부서가 B 부서로 변경
INSERT INTO t1 VALUES ('201404', 'B', 'C'); -- 201404에 B 부서가 C 부서로 변경
INSERT INTO t1 VALUES ('201407', 'C', 'D');
INSERT INTO t1 VALUES ('201401', 'I', 'J');
INSERT INTO t1 VALUES ('201401', 'X', 'Y');
INSERT INTO t1 VALUES ('201404', 'Y', 'Z');

COMMIT;

 

아래와 같이 계층 쿼리를 사용하면 최종 부서를 쉽게 찾을 수 있다.

-- 2
SELECT   a.bf_cd, a.af_cd
    FROM (SELECT     CONNECT_BY_ROOT (a.bf_cd) AS bf_cd
                   , a.af_cd
                   , CONNECT_BY_ISLEAF AS lf
                FROM t1 a
          CONNECT BY PRIOR a.af_cd = a.bf_cd) a
   WHERE a.lf = 1
ORDER BY a.bf_cd;

BF_CD AF_CD
----- -----
A     D
B     D
C     D
I     J
X     Z
Y     Z

6 행이 선택되었습니다.

 

최초 부서와 최종 부서만을 출력하고 싶다면 아래와 같이 루트 노드를 제한하면 된다.

-- 3
SELECT   a.*
    FROM (SELECT     CONNECT_BY_ROOT (a.bf_cd) AS bf_cd
                   , a.af_cd
                   , LEVEL AS cn
                   , SUBSTR (SYS_CONNECT_BY_PATH (a.af_cd, ','), 2) AS cd_ph
                   , SUBSTR (SYS_CONNECT_BY_PATH (a.ym, ','), 2) AS ym_ph
                   , CONNECT_BY_ISLEAF AS lf
                FROM t1 a
          START WITH a.bf_cd NOT IN (SELECT x.af_cd FROM t1 x)
          CONNECT BY PRIOR a.af_cd = a.bf_cd) a
   WHERE a.lf = 1
ORDER BY a.bf_cd;

BF_CD AF_CD CN CD_PH YM_PH                LF
----- ----- -- ----- -------------------- --
A     D      3 B,C,D 201401,201404,201407  1
I     J      1 J     201401                1
X     Z      2 Y,Z   201401,201404         1

3 행이 선택되었습니다.


'Oracle > SQL' 카테고리의 다른 글

파티션 확장 절  (0) 2014.05.10
Native LEFT OUTER JOIN 동작 개선  (0) 2014.04.19
SQL ID 생성  (0) 2013.09.24
최종 거래일이 1달 남은 ELW 만기일 조회  (0) 2012.07.12
데이터 계산 순서 구하기  (0) 2012.05.11
Posted by 정희락_