오라클“(+)”연산자


155

오래된 SQL 문을 문서화하고 향상시키기 위해 점검하고 있습니다.

DBMS는 Oracle입니다

나는 다음과 같은 문장을 이해하지 못했습니다.

select ...
from a,b
where a.id=b.id(+)

(+)연산자 에 대해 혼란스러워 포럼에서 얻을 수 없었습니다 ... (따옴표 내 + 검색도 작동하지 않았습니다).

어쨌든 SQLDeveloper의 'Explain Plan'을 사용했으며 다음과 같은 내용의 출력을 얻었습니다 HASH JOIN, RIGHT OUTER.

(+)쿼리가 끝날 때 연산자를 제거하면 차이가 있습니까? 데이터베이스를 (+)사용 하기 전에 몇 가지 조건 (예 : 인덱스 등)을 만족시켜야합니까 ? 간단한 이해 나 이것에 대해 읽을 수있는 좋은 링크를 제공해 주시면 큰 도움이 될 것입니다.

감사!


1
연산자가 아닙니다. JOIN이하는 일에 영향을주는 문법 일뿐입니다.
philipxy

답변:


186

FROM 절에서 쉼표를 사용하여 테이블 참조를 구분하는 ANSI-89 형식은 OUTER 조인을 표준화하지 않았기 때문에 OUTER JOIN에 대한 Oracle 고유 표기법입니다.

쿼리는 다음과 같이 ANSI-92 구문으로 다시 작성됩니다.

   SELECT ...
     FROM a
LEFT JOIN b ON b.id = a.id

이 링크는 JOIN의 차이점을 잘 설명합니다 .


또한 (+)작동 하지만 Oracle은 사용 하지 않는 것이 좋습니다 .

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


79
정확히 맞습니다. 머리에서 (+)를 똑바로 유지하기 위해 (왼쪽 대 오른쪽), 나는 (+)를 "일치하는 것이 없으면 NULL 값 추가"로 생각하고 싶습니다. 예를 들어, "a.id = b.id (+)"는 a.id와 일치하지 않는 경우 b.id를 NULL로 허용 함을 의미합니다.
해변

고마워
Kiran S

공식 오라클 문서에서 링크를 원할 수 있습니다 : docs.oracle.com/html/A95915_01/sqopr.htm
Vargan

27

(+) 연산자는 외부 조인을 나타냅니다. 즉, Oracle은 일치하는 항목이 없더라도 조인의 다른 쪽에서 레코드를 계속 반환합니다. 예를 들어, a와 b가 비어 있고 부서에 직원을 할당하지 않은 경우 다음 명령문은 부서에 할당되었는지 여부에 관계없이 모든 직원의 세부 사항을 리턴합니다.

select * from emp, dept where emp.dept_id=dept.dept_id(+)

간단히 말해 (+)를 제거하면 유의미한 차이가 생길 수 있지만 데이터에 따라 잠시 동안 눈치 채지 못할 수도 있습니다!


25

Oracle에서 (+)는 JOIN의 "선택적"테이블을 나타냅니다. 쿼리에서

SELECT a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id(+)

테이블 'b'에서 테이블 'a'의 LEFT OUTER JOIN입니다. 다른 쪽 (옵션 테이블 'b')에 데이터가 없을 때 데이터를 잃지 않고 테이블 'a'의 모든 데이터를 반환합니다.

왼쪽 외부 조인 다이어그램

동일한 쿼리에 대한 최신 표준 구문은 다음과 같습니다.

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b ON a.id=b.id

또는 축약 형 a.id=b.id(일부 데이터베이스에서 지원하지는 않음) :

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b USING(id)

(+)를 제거하면 정상적인 내부 조인 쿼리가됩니다.

Oracle 및 기타 데이터베이스 모두에서 이전 구문 :

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id

보다 현대적인 구문 :

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
INNER JOIN b ON a.id=b.id

또는 간단히 :

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
JOIN b ON a.id=b.id

내부 조인 다이어그램

'a'와 'b'테이블의 'id'값이 동일한 모든 데이터 만 반환하며 공통 부분을 의미합니다.

쿼리를 올바른 조인으로 만들려면

이것은 LEFT JOIN과 동일하지만 어떤 테이블이 선택적인지 전환합니다.

오른쪽 외부 조인 다이어그램

기존 Oracle 구문 :

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id(+)=b.id

최신 표준 구문 :

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
RIGHT JOIN b ON a.id=b.id

참조 및 도움말 :

https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:6585774577187

Oracle 11g에서 + 부호를 사용하여 왼쪽 외부 조인

https://www.w3schools.com/sql/sql_join_left.asp


"table1"및 "table2"원 레이블은 의미가 없습니다. 원 요소의 가장 간단한 의미는 출력 행입니다. 그런 다음 왼쪽 초승달에는 table1의 널 확장 행이 포함되고 오른쪽 초승달에는 table2의 널 확장 행이 포함됩니다. 서클에 대한 다른 의미는 모호합니다. 도표가 정확히 무엇을 의미한다고 생각합니까? 다른 사람들의 (나쁜) 프레젠테이션을 맹목적으로 복사하는 것 이외의 다른 이유는 무엇입니까?
philipxy

이제 원 a 및 b로 라벨이 지정되었습니다. 원은 a & b의 행이 아닙니다. 왼쪽 및 오른쪽 원은 왼쪽 결합 b 및 오른쪽 결합 b의 행으로 합리적으로 레이블이 지정 될 수 있습니다. 또한, 당신은 그 주위에있는 행들이 입력의 관점에서 무엇인지 설명하지 않습니다. 원 안에 무엇이 있는지 스스로 알아 내십시오. 원에 레이블 a & b를 붙이려면 각 레이블이 원과 어떤 관련이 있는지 명확하게 설명하십시오. (a & b로 레이블을 지정할 간단한 이유는 없습니다.) 녹색 영역에 올바르게 레이블을 지정하는 것이 좋습니다.
philipxy

6

실제로 + 기호는 조건문과 선택적 테이블 (조건부 내에 비어 있거나 널 (NULL) 값을 포함 할 수있는)의 측면에 직접 배치됩니다.


(+)는 열 이름 오른쪽에 즉시 표시됩니다. 이 답변은 명확하지 않습니다. "실제"란 무엇을 의미합니까? (수사적.) (그리고 당신은 아마 의미 "문을"않습니다.)
philipxy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.