조인 문의 드립니다. 0 15 903

by 쫀득이 [SQL Query] [2017.02.10 13:58:43]


상황 설명 드리면

2개의 계정에 테이블및 속성 정보가 동일 해야 하는데 수정 작업 발생시 어느 한쪽만 반영했었을 때를 대비해서 비교하는 쿼리 입니다.

비교해야 하는 테이블 목록이 정의 되어 있는 테이블은 따로 있습니다.

테이블은 대략 이렇게 되어 있습니다.

WITH TAB_LIST AS (
    SELECT 'EMP' TABLE_NM FROM DUAL
    UNION  SELECT 'DEPT' FROM DUAL
    UNION  SELECT 'PAY' FROM DUAL
    UNION  SELECT 'GROUP' FROM DUAL
    UNION  SELECT 'ADDR' FROM DUAL
    UNION  SELECT 'PRODUCT' FROM DUAL
), TMP_TAB_COLUMNS AS (
    SELECT 'HH' OWNER, 'EMP' TABLE_NAME, 1 COL_ID, '사번' COL_NM, 'VAR(20)' COL_TYPE  FROM DUAL
    UNION SELECT 'HH', 'EMP', 2, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'EMP', 3, '생년월일', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'DEPT', 1, '조직명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'DEPT', 2, '상위부서코드', 'CHAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'PAY', 1, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'PAY', 2, '월급', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'GROUP', 1, '부서명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'ADDR', 1, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'ADDR', 2, '주소', 'VAR(10)'  FROM DUAL
    
    UNION SELECT 'XX', 'EMP', 1, '사번', 'VAR(20)' FROM DUAL
    UNION SELECT 'XX', 'EMP', 2, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'DEPT', 1, '조직명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'DEPT', 2, '상위부서코드', 'NUMBER'  FROM DUAL
    UNION SELECT 'XX', 'PAY', 1, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'PAY', 2, '월급', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'PAY', 3, '급여일자', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'ADDR', 1, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'ADDR', 2, '주소', 'VAR(10)'  FROM DUAL
)

SELECT * 
  FROM TAB_LIST T
       , ( SELECT * FROM TMP_TAB_COLUMNS WHERE OWNER = 'HH' ) H
       , ( SELECT * FROM TMP_TAB_COLUMNS WHERE OWNER = 'XX' ) X
       
 WHERE T.TABLE_NM = H.TABLE_NAME(+)
   AND T.TABLE_NM = X.TABLE_NAME(+)

 

제 짧은 지식으로 생각 했을때는 검증해야 할 테이블 목록이 있는 TAB_LIST 를 기준 삼아 A=H(+), A=X(+) 이렇게 하면  A=H(+)=X(+) 이렇게 나올거 생각 했는데 H=X의 곱이 나오더라구요.

해서 급한데로 MINUS 연산자로 H - X 랑 X - H 해서 서로 상이 한거는 식별 하고 대상목록에는 있는데 양쪽 계정에 테이블이 없는 경우 따로 또 조회를 해서 대충 화면상에 아웃풋은 나오는데 효율적이지 못한거 같아서요

제가 원하는건 A=H(+)=X(+) 이렇게 나오는건데 조인을 어떻게 해야지 이렇게 나올수 있을까요??

답변 부탁 드립니다.~!

 

by 랑에1 [2017.02.10 14:20:55]

원하시는 결과가 정확히 어떤거예요?

내용만 봐서는 MINUS로 하시면 될 것 같은데요.


by 쫀득이 [2017.02.10 14:28:59]

원하는 결과는 이렇게 입니다.

EMP HH EMP 1 사번 VAR(20) XX EMP 1 사번 VAR(20)
EMP HH EMP 2 성명 VAR(10) XX EMP 2 성명 VAR(10)
EMP HH EMP 3 생년월일 VAR(10)          
DEPT HH DEPT 1 조직명 VAR(10) XX DEPT 1 조직명 VAR(10)
DEPT HH DEPT 2 상위부서코드 CHAR(10) XX DEPT 2 상위부서코드 NUMBER
PAY HH PAY 1 성명 VAR(10) XX PAY 1 성명 VAR(10)
PAY HH PAY 2 월급 VAR(10) XX PAY 2 월급 VAR(10)
PAY           XX PAY 3 급여일자 VAR(10)
ADDR HH ADDR 1 성명 VAR(10) XX ADDR 1 성명 VAR(10)
ADDR HH ADDR 2 주소 VAR(10) XX ADDR 2 주소 VAR(10)
PRODUCT                  

 


by 개발뉴비 [2017.02.10 14:30:38]
-- 이런 결과를 원하는게 아닌가 하네요...
-- 질문 하실 때 결과가 어떻게 나와야 하는지 표 형태 등으로 보여주시면
-- 답변하시는 분들이 알기 쉬울겁니다.

WITH TAB_LIST AS (
    SELECT 'EMP' TABLE_NM FROM DUAL
    UNION  SELECT 'DEPT' FROM DUAL
    UNION  SELECT 'PAY' FROM DUAL
    UNION  SELECT 'GROUP' FROM DUAL
    UNION  SELECT 'ADDR' FROM DUAL
    UNION  SELECT 'PRODUCT' FROM DUAL
), TMP_TAB_COLUMNS AS (
    SELECT 'HH' OWNER, 'EMP' TABLE_NAME, 1 COL_ID, '사번' COL_NM, 'VAR(20)' COL_TYPE  FROM DUAL
    UNION SELECT 'HH', 'EMP', 2, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'EMP', 3, '생년월일', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'DEPT', 1, '조직명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'DEPT', 2, '상위부서코드', 'CHAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'PAY', 1, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'PAY', 2, '월급', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'GROUP', 1, '부서명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'ADDR', 1, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'HH', 'ADDR', 2, '주소', 'VAR(10)'  FROM DUAL
    
    UNION SELECT 'XX', 'EMP', 1, '사번', 'VAR(20)' FROM DUAL
    UNION SELECT 'XX', 'EMP', 2, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'DEPT', 1, '조직명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'DEPT', 2, '상위부서코드', 'NUMBER'  FROM DUAL
    UNION SELECT 'XX', 'PAY', 1, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'PAY', 2, '월급', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'PAY', 3, '급여일자', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'ADDR', 1, '성명', 'VAR(10)'  FROM DUAL
    UNION SELECT 'XX', 'ADDR', 2, '주소', 'VAR(10)'  FROM DUAL
)

SELECT * 
  FROM TAB_LIST T
       , ( SELECT * FROM TMP_TAB_COLUMNS WHERE OWNER = 'HH' ) H
       , ( SELECT * FROM TMP_TAB_COLUMNS WHERE OWNER = 'XX' ) X
       
 WHERE T.TABLE_NM = H.TABLE_NAME(+)
   AND H.TABLE_NAME = X.TABLE_NAME(+)
   AND H.COL_ID = X.COL_ID(+)

 


by 쫀득이 [2017.02.10 14:34:27]

개발뉴비님 답변 감사 합니다. 알려 주신대로 도 생각은 해봤는데 그렇게 했을때는 

PAY                             XX PAY 3 급여일자 VAR(10)

 

이게 안나옵니다. ㅜ.ㅜ 

다음부터는 원하는 결과를 본문에 넣도록 하겠습니다. ㅎㅎ 


by jkson [2017.02.10 14:48:18]

TAB_LIST에만 존재하는 TABLE_NM도 있나요?

그게 아니라면

SELECT *
   FROM ( SELECT * FROM TMP_TAB_COLUMNS WHERE OWNER = 'HH' ) H
        FULL OUTER JOIN
        ( SELECT * FROM TMP_TAB_COLUMNS WHERE OWNER = 'XX' ) X
        ON (H.TABLE_NAME = X.TABLE_NAME
        AND H.COL_ID = X.COL_ID) 

 


by 쫀득이 [2017.02.10 14:51:32]

음 정상적인 경우에는 그런건 없습니다.  제가 예시에 "PRODUCT" 을 넣은 이유는 작업자가 실수로라도  HH 계정과 XX계정에 테이블을 드랍했었을때를 생각 한겁니다.

정장적인 경우에는 TAB_LIST 에만 존재하는 TABLE_NM 은 없습니다.


by jkson [2017.02.10 14:53:01]
-- TAB_LIST에만 존재할 수 있으면
SELECT * 
  FROM TAB_LIST A
       LEFT OUTER JOIN 
       ( 
        SELECT H.OWNER OWNER_H, H.TABLE_NAME TABLE_NAME_H, H.COL_ID COL_ID_H
              ,H.COL_NM COL_NM_H, H.COL_TYPE COL_TYPE_H
              ,X.OWNER OWNER_X, X.TABLE_NAME TABLE_NAME_X, X.COL_ID COL_ID_X
              ,X.COL_NM COL_NM_X, X.COL_TYPE COL_TYPE_X
              ,NVL(H.TABLE_NAME,X.TABLE_NAME) TABLE_NAME
           FROM ( SELECT * FROM TMP_TAB_COLUMNS WHERE OWNER = 'HH' ) H
                FULL OUTER JOIN
                ( SELECT * FROM TMP_TAB_COLUMNS WHERE OWNER = 'XX' ) X
                ON (H.TABLE_NAME = X.TABLE_NAME
                AND H.COL_ID = X.COL_ID) 
       ) B
       ON A.TABLE_NM = B.TABLE_NAME

 

--> 삽질이었습니다ㅋㅋ 아.. 부끄..ㅠ


by 마농 [2017.02.10 14:55:49]
SELECT a.table_nm
     , b.col_id
     , MIN(DECODE(b.owner, 'HH', b.col_nm  )) hh_col_nm
     , MIN(DECODE(b.owner, 'HH', b.col_type)) hh_col_type
     , MIN(DECODE(b.owner, 'XX', b.col_nm  )) xx_col_nm
     , MIN(DECODE(b.owner, 'XX', b.col_type)) xx_col_type
  FROM tab_list a
     , tmp_tab_columns b
 WHERE a.table_nm = b.table_name(+)
 GROUP BY a.table_nm, b.col_id
 ORDER BY a.table_nm, b.col_id
;

 


by jkson [2017.02.10 14:56:37]

헛ㅋ 넘 쉽네요.


by 랑에1 [2017.02.10 15:04:14]

잠깐 쪼물거리고 있으면 늘 모범답안이 ㅋㅋ


by 개발뉴비 [2017.02.10 15:04:40]

캬.. 왜 아무리 생각해도 이런 방법은 떠오르질 않는건지....


by 쫀득이 [2017.02.10 15:01:34]

아 FULL OUTER JOIN 이 있군요.

원하는 결과 나왔습니다.~! 답변 정말 감사 드립니다. 

 

 


by 쫀득이 [2017.02.10 15:06:29]

와~! 마농님 알려주셔서 정말 감사 드립니다.

이제 이게 왜 되는지 이해를 좀 해봐야 겠네요...... ㅎㅎㅎ;;

답변 주신 랑에1님 개발뉴비님 jkson님 마농님 감사 합니다.~!!~


by jkson [2017.02.10 15:09:01]

혹시나 해서 말씀 드리는데 마농님 쿼리 쓰세요 성능상 논리상 훨씬 좋은 쿼리입니다.


by 쫀득이 [2017.02.10 15:14:12]

ㅎㅎㅎ 넵 그럴려구요 ^^ 신경 써주셔서 감사 합니다.

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입