2012년 2월 17일 금요일

join(=inner join) 과 left join(=left outer join) 의 비교

join 의 개념에 대해서 혼동하는 사람도 많고, inner join 과 outer join 에 대해서 혼동하는 사람도 많다. 두 개의 개념을 예제로 비교해보자.

1. join

join 은 inner join 을 줄여서 join 이라고 통칭한다고 생각하면 된다. 물론 inner join 이라고 써도 무방하나...손가락 아프다...

아래 예제를 보자.

with man as (
    select 'A' as blood, '홍길동' as name from dual union all
    select 'A', '이차돌' from dual union all
    select 'AB', '박호신' from dual union all
    select 'AB', '차명수' from dual union all
    select 'O', '유재석' from dual union all
    select 'B', '정준하' from dual union all
    select 'A', '하하' from dual union all
    select 'B', '엄태웅' from dual union all
    select 'O', '이승기' from dual union all
    select 'A', '이수근' from dual union all
    select 'AB', '이특' from dual),
  woman as (
    select 'A' as blood, '김태연' as name from dual union all
    select 'A', '이소라' from dual union all
    select 'B', '박신애' from dual union all
    select 'AB', '차소연' from dual)
select A.*, B.*
from man A
  join woman B
    on A.blood = B.blood
order by A.blood, A.name, B.name

결과는 다음과 같다.

A    이수근    A    김태연
A    이수근    A    이소라
A    이차돌    A    김태연
A    이차돌    A    이소라
A    하하    A    김태연
A    하하    A    이소라
A    홍길동    A    김태연
A    홍길동    A    이소라
AB    박호신    AB    차소연
AB    이특    AB    차소연
AB    차명수    AB    차소연
B    엄태웅    B    박신애
B    정준하    B    박신애

무엇을 느끼시는가? 결국 같은 혈액형(blood)끼리만 짝을 지을 수 있다는 조건을 미팅장에서 제시했다면...저런 조합이 가능하다! 라고 목록을 보여주는 것 같지 않은가?

그렇다. 그것이 바로 join 이다.

불쌍하게도 여자들 중에 O 형이 없다. 그래서 O 형 남자인 유재석과 이승기는 파트너 없는 불쌍한 신세가 된 것이다. 이것이 inner join 이다. 가능성 있는 것들을 묶어주는 것...

2. outer join

흔히 DB 에서 left join 만 언급한다. 그 이유는 표준SQL 에서는 left outer join 만 지원하기 때문이다. 오라클이나 SQL Server 에서는 A.blood(+) = B.blood 나 A.blood =* B.blood 와 같이 표준SQL 형태가 아닌 독자적인 outer join 을 제공하며, right outer join 도 지원하지만 간혹 꼬여서 값이 원하는 형태대로 나오지 않는 경우가 있다. 그러므로 가급적 표준SQL 로 작성하자.

위의 예제를 조금만 바꿔보겠다.

with man as (
    select 'A' as blood, '홍길동' as name from dual union all
    select 'A', '이차돌' from dual union all
    select 'AB', '박호신' from dual union all
    select 'AB', '차명수' from dual union all
    select 'O', '유재석' from dual union all
    select 'B', '정준하' from dual union all
    select 'A', '하하' from dual union all
    select 'B', '엄태웅' from dual union all
    select 'O', '이승기' from dual union all
    select 'A', '이수근' from dual union all
    select 'AB', '이특' from dual),
  woman as (
    select 'A' as blood, '김태연' as name from dual union all
    select 'A', '이소라' from dual union all
    select 'B', '박신애' from dual union all
    select 'AB', '차소연' from dual)
select A.*, B.*
from man A
  left join woman B
    on A.blood = B.blood
order by A.blood, A.name, B.name

결과는 다음과 같다.

A    이수근    A    김태연
A    이수근    A    이소라
A    이차돌    A    김태연
A    이차돌    A    이소라
A    하하    A    김태연
A    하하    A    이소라
A    홍길동    A    김태연
A    홍길동    A    이소라
AB    박호신    AB    차소연
AB    이특    AB    차소연
AB    차명수    AB    차소연
B    엄태웅    B    박신애
B    정준하    B    박신애
O    유재석       
O    이승기       

join 과 달리 유재석과 이승기의 이름이 등장했다. 그런데 옆에 여자가 없다.
그렇다. left join 은 왼쪽을 기준으로 오른쪽의 값을 붙여주되, 값이 없으면 null 로 표시를 하는 것이다. 그러므로 왼쪽의 값들은 모두 등장을 하는 것이다.
그럼 반대로 여자를 기준으로 남자를 붙이면?

with man as (
    select 'A' as blood, '홍길동' as name from dual union all
    select 'A', '이차돌' from dual union all
    select 'AB', '박호신' from dual union all
    select 'AB', '차명수' from dual union all
    select 'O', '유재석' from dual union all
    select 'B', '정준하' from dual union all
    select 'A', '하하' from dual union all
    select 'B', '엄태웅' from dual union all
    select 'O', '이승기' from dual union all
    select 'A', '이수근' from dual union all
    select 'AB', '이특' from dual),
  woman as (
    select 'A' as blood, '김태연' as name from dual union all
    select 'A', '이소라' from dual union all
    select 'B', '박신애' from dual union all
    select 'AB', '차소연' from dual)
select A.*, B.*
from woman A
  left join man B
    on A.blood = B.blood
order by A.blood, A.name, B.name

결과는 다음과 같다.

A    김태연    A    이수근
A    김태연    A    이차돌
A    김태연    A    하하
A    김태연    A    홍길동
A    이소라    A    이수근
A    이소라    A    이차돌
A    이소라    A    하하
A    이소라    A    홍길동
AB    차소연    AB    박호신
AB    차소연    AB    이특
AB    차소연    AB    차명수
B    박신애    B    엄태웅
B    박신애    B    정준하

역시나 유재석과 이승기의 이름이 사라졌다. 기준이 되는 여자 테이블에 O 형이 없기 때문에 붙을 곳이 없어서이다.

이렇게 outer join 은 기준이 되는 것에게 값을 붙여준다고 생각하면 편할 것이다. 그래서 사실 outer join 은 두 개의 테이블이 1:1 혹은 1:0 인 값들이 존재할 때 많이 쓰이게 되는 것 같다.

join 과의 가장 큰 차이는 기준이 되는 테이블의 값은 어쨌든 다 나온다는 것! 그것을 명심하면 되겠다.

댓글 없음:

댓글 쓰기