[Oracle] JOIN (2) - OUTER JOIN, SELF JOIN(오라클, ANSI 문법)
이번에는 CROSS JOIN과 INNER JOIN에 이어서 OUTER JOIN과 SELF JOIN을 살펴볼 것이다. (CROSS JOIN과 INNER JOIN 링크는 아래에 남겨두었다.)
JOIN 실습을 위한 테이블1, 테이블2, 테이블3 세 개의 테이블은 아래와 같다.
OUTER JOIN(외부 조인)
INNER JOIN이 모든 테이블에 데이터가 존재하는 경우에만 결과를 출력했다면 OUTER JOIN은 조인 조건에 만족하지 않는 데이터도 결과로 출력하기 위해 사용한다. 한쪽 테이블에는 데이터가 있고 한쪽 테이블에는 없는 경우 데이터가 있는 쪽 테이블 내용을 전부 출력할 수 있기 때문이다.
OUTER JOIN에는 LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN이 있다.
• LEFT OUTER JOIN
LEFT OUTER JOIN은 왼쪽 테이블의 모든 데이터와 오른쪽 테이블의 관련 데이터를 추출하는 방법이다. 오라클 문법에서는 데이터가 없는 쪽에 (+)를 표시하지만, ANSI문법에서는 모든 데이터가 출력되는 쪽을 기준으로 LEFT 혹은 RIGHT JOIN을 한다는 점에 유념해야 한다.
-- ORACLE --
SELECT 테이블1.이름, 테이블1.색깔, 테이블2.color, 테이블2.fruit
FROM 테이블1, 테이블2
WHERE 테이블1.색깔 = 테이블2.COLOR(+);
-- ANSI --
SELECT 테이블1.이름, 테이블1.색깔, 테이블2.color, 테이블2.fruit
FROM 테이블1 LEFT [OUTER] JOIN 테이블2
ON 테이블1.색깔 = 테이블2.COLOR;
*OUTER 키워드 생략 가능
위의 LEFT OUTER JOIN 결과는 아래와 같다. 왼쪽에 있는 테이블1을 기준으로 조건에 맞는 테이블2의 데이터가 있으면 함께 출력되고, 없으면 NULL 값으로 결과에 추가된 것을 볼 수 있다.
• RIGHT OUTER JOIN
RIGHT OUTER JOIN은 오른쪽 테이블의 모든 데이터와 왼쪽 테이블의 관련 데이터를 추출하는 방법이다. 오라클 문법을 살펴보면 LEFT OUTER JOIN과 다르게 (+)의 위치가 반대편에 붙은 것을 확인할 수 있다.
-- ORACLE --
SELECT 테이블1.이름, 테이블1.색깔, 테이블2.color, 테이블2.fruit
FROM 테이블1, 테이블2
WHERE 테이블1.색깔(+) = 테이블2.COLOR;
-- ANSI --
SELECT 테이블1.이름, 테이블1.색깔, 테이블2.color, 테이블2.fruit
FROM 테이블1 RIGHT [OUTER] JOIN 테이블2
ON 테이블1.색깔 = 테이블2.COLOR;
*OUTER 키워드 생략 가능
위의 RIGHT OUTER JOIN 결과는 아래와 같다. LEFT OUTER JOIN 결과와 다르게 오른쪽에 있는 테이블2의 데이터가 모두 표시되었다.
• FULL OUTER JOIN
양쪽의 모든 데이터를 추출하는 방법으로 LEFT OUTER JOIN과 RIGHT OUTER JOIN을 합친 것과 같다.
-- ORACLE --
SELECT 테이블1.이름, 테이블1.색깔, 테이블2.color, 테이블2.fruit
FROM 테이블1, 테이블2
WHERE 테이블1.색깔 = 테이블2.color(+)
UNION
SELECT 테이블1.이름, 테이블1.색깔, 테이블2.color, 테이블2.fruit
FROM 테이블1, 테이블2
WHERE 테이블1.색깔(+) = 테이블2.color;
-- ANSI --
SELECT 테이블1.이름, 테이블1.색깔, 테이블2.color, 테이블2.fruit
FROM 테이블1 FULL [OUTER] JOIN 테이블2
ON 테이블1.색깔 = 테이블2.color;
오라클 문법은 집합 연산자 UNION으로 LIFT OUTER JOIN과 RIGHT OUTER JOIN을 합쳐서 FULL OUTER JOIN을 할 수 있다. ANSI 문법의 경우 위처럼 더욱 간단하게 작성할 수 있으며 결과는 아래와 같다. 참고로 오라클 문법 쿼리문을 실행하면 UNION은 정렬을 포함하기 때문에 아래의 결과와 행의 순서가 다를 수 있다.
SELF JOIN
SELF JOIN은 같은 테이블에서 2개 이상의 속성(컬럼)을 연결하는 방법이다. 원하는 데이터가 하나의 테이블에 모두 있을 경우 사용한다. SELF JOIN은 하나의 테이블을 별명만 다르게 하여 사용할 뿐 다른 조인 방법과 크게 다르지 않다.
-- ORACLE --
SELECT a.이름 AS "이름", b.이름 AS "단짝"
FROM 테이블1 a, 테이블1 b
WHERE a.번호 = b.단짝;
-- ANSI --
SELECT a.이름 AS "이름", b.이름 AS "단짝"
FROM 테이블1 a JOIN 테이블1 b
ON a.번호 = b.단짝;
테이블1의 경우 각 행마다 번호에 맞는 단짝 친구가 존재한다. 위의 쿼리문은 사람마다 누가 단짝인지 단짝의 이름을 출력하고 있으며, 모든 데이터가 테이블1 안에 있으므로 SELF JOIN을 하였다. 결과는 아래와 같다.
이렇게 OUTER JOIN과 SELF JOIN까지 JOIN을 모두 살펴보았다. INNER JOIN과 CROSS JOIN은 아래 글에서 확인할 수 있다.
[Oracle] JOIN (1) - CROSS JOIN, INNER JOIN(오라클, ANSI 문법)
JOIN은 두 개 이상의 테이블을 연결하여 데이터를 조회하는 방법이다. 관계형 DBMS는 성능 향상을 위해 정규화를 진행하기 때문에 테이블을 연결하여 조회하는 JOIN은 매우 중요한 기능이다. JOIN
worldag.tistory.com
처음 SQL을 접할 때 JOIN은 헷갈리는 부분 중 하나였기 때문에 이렇게 직접 실습하며 정리해 봤다. 간단하게 테이블 생성해서 정리하면 되겠지 싶었는데 조인 결과가 잘 드러나도록 혹은 조인에 맞게 계속 테이블 수정을 하다 보니 시간이 꽤 걸렸다. 그럼에도 테이블명부터 각 테이블의 의미(?)가 담기지 않은 점은 아쉽다. 그래도 혹시 따라서 실습하고 싶은 분이 있으시다면 댓글에 남겨둔 테이블1, 테이블2, 테이블3의 CREATE문과 INSERT문을 참고하면 좋을 것 같다.