Oracle 11g에서 + 로그인을 사용하여 왼쪽 외부 조인


81

아래 두 쿼리가 Left Outer Join 또는 Right Outer Join의 예인지 여부를 알 수 있습니까 ??

Table Part:
Name         Null?       Type
PART_ID      NOT NULL    VARCHAR2(4)
SUPPLIER_ID              VARCHAR2(4)

PART_ID SUPPLIER_ID
P1      S1
P2      S2
P3  
P4  

Table Supplier:
Name            Null?     Type
SUPPLIER_ID NOT NULL      VARCHAR2(4)
SUPPLIER_NAME   NOT NULL  VARCHAR2(20)

SUPPLIER_ID  SUPPLIER_NAME
S1           Supplier#1
S2           Supplier#2
S3           Supplier#3

공급 업체의 공급 여부에 관계없이 모든 부품을 표시합니다.

P.Part_Id, S.Supplier_Name 선택
파트 P, 공급자 S에서
어디서 P.Supplier_Id = S.Supplier_Id (+)

P.Part_Id, S.Supplier_Name 선택
파트 P, 공급자 S에서
S.Supplier_Id (+) = P.Supplier_Id

26
'(+)'표기법을 사용하지 말고 명시 적 조인을 사용하도록 쿼리를 업그레이드해야합니다.
Jonathan Leffler 2011

1
@JonathanLeffler 100 % 동의합니다. 문제는 내가 표준 표기법을 따르고 싶지 않은 사람들과 함께 일한다는 것입니다. 표준 표기법으로 새 ​​쿼리를 작성하지만 이전 쿼리를 수정하면 곧 촬영할 것입니다.
Luc M

3
@JonathanLeffler Oracle을 사용하지 않는 한 동의합니다. Oracle은 현재 내부적으로 ansi 구문과 (+) 연산자를 처리하지 않습니다. ansi 구문 사용을 권장하지만 :) docs.oracle.com/cd/B28359_01/server.111/b28286/queries006.htm
신화

7
@Amyth이 방식으로 오래된 댓글에 대해 죄송하지만 검색 에서이 질문에 왔습니다. 나로서는 오라클의 권장 사항을 정반대로 이해합니다. 링크에서 : " Oracle 은 Oracle 조인 연산자 대신 FROM 절 OUTER JOIN 구문을 사용할 것을 권장합니다 . Oracle 조인 연산자 (+)를 사용하는 외부 조인 쿼리에는 다음 규칙과 제한 사항이 적용됩니다. 절 OUTER로부터 JOIN 구문을 ... "
실뱅 레녹스

오래된 응답도 유감입니다 :),하지만 오라클이 말하는 것과 쿼리를 최적화하기 위해 통계가 작동하는 방식은 두 가지이며, 오라클이 내부 최적화 프로그램의 발전과 함께 입장을 변경했을 수도 있습니다
신화

답변:


188

TableA LEFT OUTER JOIN TableB와 동일합니다 TableB RIGHT OUTER JOIN Table A.

Oracle에서는 (+)JOIN의 "선택적"테이블을 나타냅니다. 따라서 첫 번째 쿼리에서는 P LEFT OUTER JOIN S. 두 번째 쿼리에서는 S RIGHT OUTER JOIN P. 기능적으로 동일합니다.

용어에서 RIGHT 또는 LEFT는 조인의 어느쪽에 항상 레코드가 있는지 지정하고 다른 쪽은 null 일 수 있습니다. A의 그래서 P LEFT OUTER JOIN S, P그것은에 있기 때문에 항상 기록이됩니다 LEFT만, S널 (null)이 될 수 있습니다.

추가 설명 은 java2s.com의이 예제를 참조하십시오 .


명확히하기 위해 용어는 시각화를 돕기 위해 존재하기 때문에 중요하지 않다고 말하는 것 같습니다. 중요한 것은 작동 방식의 개념을 이해하는 것입니다.


오른쪽 대 왼쪽

암시 적 조인 구문에서 RIGHT와 LEFT를 결정할 때 무엇이 ​​중요한지에 대해 약간의 혼란을 보았습니다.

왼쪽 외부 조인

SELECT *
FROM A, B
WHERE A.column = B.column(+)

오른쪽 외부 조인

SELECT *
FROM A, B
WHERE B.column(+) = A.column

내가 한 것은 WHERE 절에서 용어의 측면을 바꾸는 것이지만 여전히 기능적으로 동일합니다. (그에 대한 자세한 내용은 내 답변의 위쪽을 참조하십시오.)의 배치는 (+)RIGHT 또는 LEFT를 결정합니다. (구체적 (+)으로가 오른쪽에 있으면 LEFT JOIN (+), 왼쪽에 있으면 RIGHT JOIN입니다.)


JOIN 유형

JOIN의 두 가지 스타일은 암시 적 JOIN명시 적 JOIN 입니다. JOIN을 작성하는 다른 스타일이지만 기능적으로는 동일합니다.

이 SO 질문을 참조하십시오 .

암시 적 조인은 단순히 모든 테이블을 함께 나열합니다. 결합 조건은 WHERE 절에 지정됩니다.

암시 적 조인

SELECT *
FROM A, B
WHERE A.column = B.column(+)

명시 적 조인은 조인 조건을 WHERE 절 대신 특정 테이블의 포함과 연관시킵니다.

명시 적 조인

SELECT *
FROM A
LEFT OUTER JOIN B ON A.column = B.column

이러한 암시 적 조인은 읽고 이해하기가 더 어려울 수 있으며 조인 조건이 다른 WHERE 조건에서 혼합되기 때문에 몇 가지 제한 사항이 있습니다. 따라서 암시 적 JOIN은 일반적으로 명시 적 구문을 선호하는 방식으로 권장됩니다.


3
맞습니다, 이제 알았습니다-JOIN은 (+)의 존재에 의해 암시 적으로 생성됩니다. 멋있는.
Kerrek SB

2
@Mike : 이것이 + 구문이 작동하는 방식입니다. "선택 사항"을 의미하므로 "모든 부품 나열, 선택적으로 공급자 일치"와 같이 읽으십시오.
Kerrek SB

2
@Mike : 당신이 무엇을 선택하고 있는지 아는 한, 당신이 그것을 어떻게 부르는지는 정말로 중요하지 않습니다. 그러나 자신에게 호의를 베풀고 JOIN대신 관용구 구문을 사용하십시오! 그러면 혼란의 여지가 없습니다.
Kerrek SB 2011

1
@TomJMuthirenthi 명시 적 FULL OUTER JOIN구문을 사용하지 않고 UNION [ALL]두 개의 결과 집합 이 필요 합니다. 하나는 A = B (+)에 대한 것이고 다른 하나는 B = A (+)에 대한 것입니다. 이 질문의 예 .
Wiseguy

1
"(+)"는 널의 하위 행을 생성하는 테이블의 열에 있습니다.
philipxy

9

이 두 쿼리가 수행되고 OUTER JOIN있습니다. 아래 참조

Oracle은 Oracle 조인 연산자보다 FROM 절 OUTER JOIN 구문을 사용하는 것이 좋습니다. Oracle 조인 연산자 (+)를 사용하는 외부 조인 쿼리에는 FROM 절 OUTER JOIN 구문에 적용되지 않는 다음 규칙 및 제한이 적용됩니다.

  • FROM 절 조인 구문도 포함하는 쿼리 블록에는 (+) 연산자를 지정할 수 없습니다.

  • (+) 연산자는 FROM 절의 WHERE 절 또는 왼쪽 상관 관계 (TABLE 절을 지정할 때)에만 나타날 수 있으며 테이블 또는 뷰의 열에 만 적용될 수 있습니다.

  • A와 B가 여러 조인 조건으로 조인되는 경우 이러한 모든 조건에서 (+) 연산자를 사용해야합니다. 그렇지 않은 경우 Oracle 데이터베이스는 단순 조인의 결과 행만 반환하지만 외부 조인의 결과가 없다는 경고 나 오류없이 반환합니다.

  • (+) 연산자는 외부 쿼리에 한 테이블을 지정하고 내부 쿼리에 다른 테이블을 지정하는 경우 외부 조인을 생성하지 않습니다.

  • 자체 조인은 유효하지만 (+) 연산자를 사용하여 테이블을 외부 조인 할 수 없습니다. 예를 들어 다음 문은 유효하지 않습니다.

    -- The following statement is not valid:
    SELECT employee_id, manager_id
       FROM employees
       WHERE employees.manager_id(+) = employees.employee_id;
    

    그러나 다음 자체 조인은 유효합니다.

    SELECT e1.employee_id, e1.manager_id, e2.employee_id
       FROM employees e1, employees e2
       WHERE e1.manager_id(+) = e2.employee_id
       ORDER BY e1.employee_id, e1.manager_id, e2.employee_id;
    
  • (+) 연산자는 임의의식이 아닌 열에 만 적용 할 수 있습니다. 그러나 임의의 표현식은 (+) 연산자로 표시된 하나 이상의 열을 포함 할 수 있습니다.

  • (+) 연산자를 포함하는 WHERE 조건은 OR 논리 연산자를 사용하여 다른 조건과 결합 할 수 없습니다.

  • WHERE 조건은 IN 비교 조건을 사용하여 (+) 연산자로 표시된 열을 식과 비교할 수 없습니다.

WHERE 절에 테이블 B의 열을 상수와 비교하는 조건이 포함 된 경우 Oracle이이 열에 대해 Null을 생성 한 테이블 A의 행을 반환하도록 (+) 연산자를 열에 적용해야합니다. 그렇지 않으면 Oracle은 단순 조인의 결과 만 반환합니다.

두 개 이상의 테이블 쌍의 외부 조인을 수행하는 쿼리에서 단일 테이블은 하나의 다른 테이블에 대해서만 Null 생성 테이블이 될 수 있습니다. 따라서 A와 B의 조인 조건과 B와 C의 조인 조건에서 B의 열에는 (+) 연산자를 적용 할 수 없습니다. 외부 조인의 구문은 SELECT를 참조하십시오.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries006.htm 에서 가져옴


4

위의 답변에서 모순을 보았고 Oracle 12c에서 다음을 시도했으며 다음이 정확합니다.

왼쪽 외부 조인

SELECT *
FROM A, B
WHERE A.column = B.column(+)

오른쪽 외부 조인

SELECT *
FROM A, B
WHERE B.column(+) = A.column

0

왼쪽 외부 조인

SELECT * FROM A, B WHERE A.column = B.column (+)

오른쪽 외부 조인

SELECT * FROM A, B WHERE A. 열 (+) = B. 열


-2

이 스레드에 잘못된 정보가 있습니다. 잘못된 정보를 복사하여 붙여 넣었습니다.

왼쪽 외부 조인

SELECT *
FROM A, B
WHERE A.column = B.column(+)

오른쪽 외부 조인

SELECT *
FROM A, B
WHERE B.column(+) = A.column

위의 내용이 잘못되었습니다 !!!!! 반대입니다. 내가 틀렸다고 판단한 방법은 다음 책에 있습니다.

Oracle OCP Introduction to Oracle 9i : SQL Exam Guide . 표 3-1에는 이에 대한 좋은 요약이 있습니다. 내가 옛날 학교에 가서 인쇄 된 책을 볼 때까지 변환 된 SQL이 제대로 작동하지 않는 이유를 알 수 없었습니다!

다음은이 책에서 한 줄씩 복사 한 요약입니다.

Oracle 외부 조인 구문 :

from tab_a a, tab_b b,                                       
where a.col_1 + = b.col_1                                     

ANSI / ISO 동등 :

from tab_a a left outer join  
tab_b b on a.col_1 = b.col_1

위에 게시 된 내용의 반대입니다. 나는이 책에 정오표가있을 수 있다고 생각하지만 나는이 글에있는 것보다이 책을 더 신뢰한다. 큰 소리로 울기위한 시험 가이드입니다 ...


4
이것은 Oracle Database 10g SQL (Osborne ORACLE Press Series) 1st edition (2004 년 2 월 20 일)에서 발췌 한 내 답변에서 링크 한 내용과 모순됩니다. "왼쪽 외부 조인에서 외부 조인 연산자는 실제로 같음 연산자의 오른쪽. " 다음은 예제의 데모입니다 . a.col_1(+) = b.col_1LEFT JOIN이 아니라 RIGHT JOIN 의 결과입니다 .
Wiseguy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.