sql outer join 은 inner join과 다르게 왼쪽, 혹은 오른쪽 table의 결과를 보존합니다. left outer join의 경우, 왼쪽 테이블을, right outer join은 오른쪽 테이블을 보존해요. 보통 left를 많이 쓰니까, left를 기준으로 설명하겠습니다.
- inner join
- outer join [현재글]
간단한 예제 데이터와 inner join
먼저, 저번에 이 글에서 소개했던 inner join을 다시 볼게요.
먼저, post table에 있는 레코드 2개입니다. 1번은 hello book이, 2번은 my name is cho가 있습니다.
다음, comment 테이블을 통해, post_id별로 댓글 갯수를 집계했습니다. id가 1인 포스트에 대해서만 1이 나왔습니다. id가 2인 것에 대해서는 하나도 나오지 않았어요.
이 쿼리는 그림 1의 결과 테이블과, 그림 2의 결과 테이블을 inner join 하는 쿼리입니다. 조건을 읽어보면, post.id와 comment_stat의 post_id가 같으면 join을 하게 됩니다.
위 그림을 봅시다. from 절에 나타난 것이 post 였습니다. 그리고, join문 뒤에 나타난 comment_stat이 있습니다. 이들을
- join에 참여하는 왼쪽 테이블 post
- join에 참여하는 오른쪽 테이블 comment_stat
이라 할게요. comment_stat에는 post_id가 1인 데이터가 있어요. 그렇기 때문에, id가 1인 post 레코드와, post_id가 1인 레코드는 join 됩니다. 그런데, post_id가 2인 데이터는 없습니다. inner join의 경우, post_id가 2인 레코드가 comment_stat 쪽에 없었기 때문에
- post의 id가 2인 것은 결과에 나타나지 않습니다.
따라서, id가 1인 것만 join이 됩니다. 결과를 볼까요?
결과는 위와 같습니다.
sql outer join
이제, 본론으로 들어가 봅시다. 결과를 보존하는 쪽이 아우터 조인이라 했는데요. 간략하게 설명을 풀어보면 아래와 같습니다.
.. from A left outer join B on A.id = B.a_id
A.id와 B.a_id가 같으면 join을 하는데 A.id가 B에 없는 경우, B쪽 결과는 null이 됩니다. 즉 왼쪽 테이블 A의 결과를 보존합니다.
이게 무슨 말인가?
이 쿼리를 실행해 봅시다. 일단, 왼쪽 테이블과 오른쪽 테이블을 봅시다.
- 왼쪽은 post이고
- 오른쪽은 comment_stat입니다.
post_id가 1인 것은 comment_stat에 있었습니다. 따라서, 이건 문제 없이 join 됩니다. 문제는 post_id가 2인 쪽이였습니다. inner join 같았으면 버려졌을 텐데요. outer left join의 경우
- 왼쪽에 있는 my name is cho와 id가 2인 데이터는 보존됩니다.
- 오른쪽 comment_stat에 post_id가 2인 것은 없었기 때문에
- comment_stat쪽 결과는 모두 nil이 됩니다.
결과를 볼까요?
id가 2인 것도 나왔음을 알 수 있습니다. 이것이 이너 조인과 차이점입니다. 이거를 조금만 더 응용해 봅시다. post_id와 cc가 null이 나왔다는 것은, comment가 없었다는 것을 의미합니다. 이 때 0이 되게 하려면 어떻게 하면 좋을까요? 이 글에서 소개드렸습니다만, postgres에서는 coalesce 함수를 쓰면 됩니다.
coalesce 함수를 사용해서, cc 값이 null이라면 0이 나오게끔 합시다.
그러면 2번 post에 대한 댓글이 없을 때, null 대신에 0이 나온다는 것을 알 수 있습니다. 다음에 몇 가지 실전 문제들을 풀어보면서 완벽하게 이해해 보도록 합시다.