블로그 이미지
SITD

카테고리

분류 전체보기 (34)
1.DB (4)
2.OS (3)
3.PROGRAMMING (14)
4.학업 (0)
5.영어 (0)
6.KSIT (5)
7.증권 (1)
8.EXCEL (0)
9.Graduate (2)
기타 (5)
Total
Today
Yesterday

달력

« » 2024.4
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

공지사항

태그목록

최근에 올라온 글

추가 by 2012.07.13
NVL로 아우터를 따라할 수 있지만 제약이 있다. 만약 조인을 할 때 (+)가 하나도 없이 NVL로만 할 경우...해당 테이블을 찾아가지 못해서 결과가 안나오는 듯 하다.

아래는 거 쿼리이다.

SELECT A.acnt_no,
B.acnt_no,
C.item_cd
  FROM WR_TB415 A,
  AC_TBM_ACNT B,
WR_TB504 C
 WHERE A.acnt_no = B.acnt_no
   AND A.acnt_no = C.acnt_no (+)
   AND A.item_cd = NVL(C.item_cd, A.item_cd)
   AND A.acnt_no IN ('00011222201')
/
SELECT A.acnt_no,
B.acnt_no,
C.item_cd
  FROM WR_TB415 A,
  AC_TBM_ACNT B,
WR_TB504 C
 WHERE A.acnt_no = B.acnt_no
   AND A.acnt_no = C.acnt_no (+)
   AND A.item_cd = C.item_cd (+)
   AND A.acnt_no IN ('00011222201')


=> 결과 동일
SELECT A.acnt_no,
B.item_cd
  FROM WR_TB415 A,
  WR_TB300 B
 WHERE A.item_cd = B.item_cd (+)
   AND A.acnt_no = '10006000101'
/
SELECT A.acnt_no,
B.item_cd
  FROM WR_TB415 A,
  WR_TB300 B
 WHERE A.item_cd = NVL(B.item_cd, A.item_cd)
   AND A.acnt_no = '10006000101'
=> 결과가 상이함.





(+)의 기능에 대해
다음과 같은 쿼리가 있을 때,

SELECT A.item,
A.item_name,
A.dept,
A.dept_nm
  FROM ITEM_CODE A,
  DEPT_CODE B
 WHERE A.dept = B.dept (+)
   AND B.dept_nm (+) = 'ASCII'
/

이 쿼리의 처리 순서가 네스티드 루프 기준으로 ITEM_CODE테이블을 풀 스캔해서 해당 테이블의 로우 1건을 가져온 후, A.dept를 ITEM_CODE에서 가져온 로우의 값으로 치환,
이후 DEPT_CODE테이블 검색시 실제론 A.dept에 들어있는 값을 이용해서 찾는다고 알고 있습니다.

이때 '해당 B.dept에 (+)이 있으면 B의 값이 없더라도 A로우를 출력'하는 거 같던데,

이렇게 이해해도 될까요?

즉, (+)가 붙는 조건은 조인 혹은 검색시 조회가 안되더라도 값 없음으로 해당 로우 자체를 조건에서 제외하는게 아니라, 그대로 진행(즉, B테이블 못 읽음)한다라고 이해하는게 맞을까요?
이는 조인 조건이 아닌 AND B.dept_nm (+) = 'ASCII'의 경우에도 똑같이 이해해도 될까 궁금합니다.

답변 부탁드립니다 m(_ _)m


답변 by ProDBA 아바롱님.


네.. 큰 맥락에서 그렇게 이해하시는게 맞습니다.
다만 아우터 조인의 개념에 조금 더 부연을 드리자면
 
(+) 기호가 붙지 않은 쪽(OUTER TABLE, DRIVING TABLE)의 테이블 건수 이상이 출력된다는 것입니다.
즉, 위와 같은 예제에서는 A 테이블에 아무런 조건이 없으므로 최소한 A의 모든 ROW가 출력됩니다.
물론 조인 조건의 컬럼에 따라 B 테이블에서 1:M으로 조인되어지면 A의 모든 ROW가 M의 배수 만큼 중복으로 출력됩니다.
그러므로, 최소한 A의 건수이상 출력됩니다.
 
또한, 이해하고 계신 개념을 조금만 보정 하자면 B 테이블을 읽지 않는 것이 아니고
A에는 존재하는 데이터가 B에서 조인되어지지 않거나 혹은 조인되어 지더라도 B의 필터링 조건에서 제외되더라도
A를 출력시키는 개념입니다.
일반적인 INNER JOIN은 위와 반대로 조인되어 지지 않거나 필터링 조건에서 제외되면 A를 출력시키지 않는 것이죠.
 
도움이 되시길 바랍니다.


추가. 
아우터는 
이너 조인 
UNION ALL
안티 조인
으로, 이너 조인에 의한 교집합 + 안티조인에 의한 A에서 B를 제외한 여집합과 같은 결과를 리턴한다.

그리고 위와 같은 원리이기 때문에,
SELECT A.item,
A.item_name,
A.dept,
A.dept_nm
  FROM ITEM_CODE A,
  DEPT_CODE B
 WHERE A.dept = B.dept (+)
   AND NVL(B.dept_nm, 'ASCII') = 'ASCII'
 
등으로 (+) 대신 널일때를 대비한 처리를 해주면 쿼리를 변경시켜도 아우터는 유지된다. 


'1.DB > ORACLE' 카테고리의 다른 글

오라클 ROWNUM  (0) 2011.04.22
Posted by SITD
, |

[펌]공부의 왕도

기타 / 2011. 5. 4. 16:38
Posted by SITD
, |

NULLS FIRST/LAST

1.DB/SQL / 2011. 4. 25. 17:28

SELECT *
  FROM (SELECT '0' aa from dual UNION ALL
SELECT '1' aa from dual UNION ALL
SELECT '2' aa from dual UNION ALL
SELECT '3' aa from dual UNION ALL
SELECT NULL   FROM DUAL)
 ORDER BY aa desc nulls first
-- ORDER BY aa desc nulls last

-- 널의 위치를 지정한다. 

'1.DB > SQL' 카테고리의 다른 글

분석함수 및 KEEP을 정리해보자.  (0) 2011.11.14
Posted by SITD
, |

최근에 달린 댓글

글 보관함