database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 40886 게시물 읽기
No. 40886
잘 이해가 안되는 SQL 결과에 대하여 질문을 드립니다.
작성자
김흥수(protokhs)
작성일
2015-07-31 11:19
조회수
7,860

 안녕하십니까?

좀 잘 이해가 안되는 SQL 결과에 대하여 왜 이렇게 되는지 고견을 듣고 싶습니다.

 

먼저 다음과 같은 SQL의 결과는 
WITH BASE_TABLE AS
(
    SELECT '1' CODE , 'A' TEXT FROM DUAL
)
SELECT
    *
FROM    BASE_TABLE A
        , DUAL B
WHERE   B.DUMMY (+) = A.CODE
/
CODE TEXT DUMMY
1 A
이렇게 나옵니다.
 
그런데 다음의 SQL은 아무런 행도 리턴하지 않습니다.
 
WITH BASE_TABLE AS
(
    SELECT '1' CODE , 'A' TEXT FROM DUAL
)
SELECT
    *
FROM    BASE_TABLE A
        , DUAL B
WHERE   B.DUMMY (+) = '1'
/
 
그런데 다음과 같이 아무 컬럼이나 되도 않게 조인을 걸면 됩니다.
 
WITH BASE_TABLE AS
(
    SELECT '1' CODE , 'A' TEXT FROM DUAL
)
SELECT
    *
FROM    BASE_TABLE A
        , DUAL B
WHERE   B.DUMMY (+) = '1'
AND     A.CODE = B.DUMMY (+)
/
CODE TEXT DUMMY
1 A
 
 
그리고 다음과 같이 ANSI 문법을 사용하면 됩니다.(결과가 나옵니다.)
 
WITH BASE_TABLE AS
(
    SELECT '1' CODE , 'A' TEXT FROM DUAL
)
SELECT
    *
FROM    BASE_TABLE A
        LEFT JOIN 
        DUAL B
        ON (
            B.DUMMY = '1'
        )
 
....... 이유가 뭘까요?
 
이 글에 대한 댓글이 총 3건 있습니다.

아우터 조인이라는게 혼자 되는게 아니라 양쪽이 있어야 되는 건데요.
두번 째 쿼리의 조건만으로는 a 와 b 가 아우터 조인이 걸린다라고 볼 수 없네요.
즉 a 를 기준으로 b 를 아우터 조인 건다라는게 명확하게 표현되어야 하는데.
두번 째 쿼리에는 기준이 a 라는게 명확하지 안네요.

마농(manon94)님이 2015-08-01 02:35에 작성한 댓글입니다.

inner join일때와는 다르게
outer join은 주어진 condition들중 어느것이 두 테이블의 join을 위해
사용될지, 어느것이 결과 filtering 위해 사용해야 할지를
따로 인식하는게 아주 중요하죠.

두번째 쿼리같은 경우는 사실상 join condition이 제공되지
않았으므로 오라클이 두 테이블을 inner cross join을 하고
dummy 컬럼의 값이 'X' 이므로 ,주어진 filtering condition인 b.dummy(+)='1' 때문에
어떤 결과도 살아남지 못하죠.

비슷한 구조를 가진 4번째 쿼리의 경우는
(우월한)ANSI 문법을 통해 dummy = '1' 이 join condition임을
명시하였으므로, A 테이블은 그대로 살고 이를 기준으로 B컬럼들은 그냥 NULL로 채워졌습니다.
filtering condition은 제공되지 않았구요.

3번째 쿼리는 말씀하신 대로 되도 않게 left join이 되었으므로
A는 그대로 살고 이를 기준으로 B는 모두 NULL이되고
B가 null이므로 filtering condition인 b.dummy(+)='1' 이 항상 true가 됩니다.

 

고서진님이 2015-08-01 18:19에 작성한 댓글입니다. Edit

 답변 감사합니다.

^^

 

그런데 그래도 저는 좀 이상하다고 생각됩니다.

and 의 의미는 ~ 이고 의 뜻입니다.

즉 a and b 인 경우의 결과가 a 의 결과보다 더 많다는 것 자체가 납득이 안 갑니다.

 

join 도 이러한 대 전제를 무시하는 것은 아니라고 봅니다.

 

그런데 마농님 말씀이 적절한 설명이라는 생각이 들면서도 반면으로는

내부적인 사항을 알고 있는 사람의 이해심이라고 생각들거든요...

 

"(+) 표기는 outer에 쓰는 거니까... "하는 것을 이해해주고 있다는 거죠...

그리고 "상수조건과 함께 사용된 (+)는 실제로는 아우터 조인이 전제된 경우만 의미가 있을 뿐이야..." 라는 것두요....

 

제 개인적인 생각에는 차라리 아우터 조인 없이 B.DUMMY (+) = '1' 이라고 하는 경우 에러가 났다면

이해가 될텐데요.... 그렇지 않네요...

그래서 그 결과로 and의 의미론이 손상되었다고 생각됩니다.

김흥수(protokhs)님이 2015-08-17 17:30에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
40890SQL 문의 입니다. ^^ [4]
이현정
2015-08-06
8252
40888pl/sql htp.p기능을 통해 사원조회 수정 삭제기능을 만드려고하는데
천범석
2015-08-03
7287
40887계층구조 데이터 구해오기[내용수정] [2]
초보
2015-07-31
8007
40886잘 이해가 안되는 SQL 결과에 대하여 질문을 드립니다. [3]
김흥수
2015-07-31
7860
40885SQL 좀 봐주세요. [2]
이현정
2015-07-30
8325
40884PL/SQL에서 TABLE명을 변수로 받아서 CURSOR 실행법..? [3]
초보자
2015-07-30
8032
40883특정 문자를 제거 후 (하이픈) 데이타 출력 방법 좀 알려 주세요. [2]
밥님
2015-07-29
7853
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.021초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다