1. JOIN이란
두개 이상의 테이블을 결합하여 데이터를 검색하는 방법입니다.
자신이 검색하고 싶은 데이터가 한개의 테이블이 아니라 여러개의 테이블에 나누어져 있다면 각테이블의 컬럼을 한개씩 가져와서 그 컬럼을 접점으로 이용하여 여러 테이블에 나누어져 있는 데이터를 한번에 검색하는데요 보통 접점으로 사용하는 컬럼은 Primary Key 혹은 Foreign Key로 두 테이블을 연결합니다. 물론 두 컬럼을 접점으로 비교하기 위해서는 같은 데이터타입을 사용하는 컬럼이어야 하는 것은 당연합니다.
그렇다면 왜 데이터를 한개의 테이블에 넣지 않고 두개의 테이블에 나누어서 넣은 후에 Join이라는 과정을 거쳐서 데이터를 가져오는지 생각해 볼 필요가 있습니다.
아래의 테이블을 게시판의 DB테이블이라고 가정을 하고 생각해 보겠습니다. 이 경우에 만약 작성자의 나이가 어떠한 이유로 변경이 되었다면 테이블의 작성자 이름을 전부 수정해 주어야 할 것입니다.
만약 게시글이 100만개 라면 100만개를 모두 수정을 해줘야만 합니다.
게시글제목 | 게시글내용 | 작성자ID | 작성자나이 |
자기소개 | 중략... | zozo123 | 24 |
Join 사용법 | 중략... | zozo123 | 24 |
해외여행 후기 | 중략... | zozo123 | 24 |
하지만 아래처럼 게시판의 테이블과 회원의 테이블이 따로 분리되어 있다면 어떨까요?
게시판의 데이터양이 얼마가 되었던간에 회원테이블에서 한번만 이름을 변경해주면 끝납니다.
만약 게시판에서 게시글 작성자의 나이나 이름의 데이터가 필요하다면 작성자 아이디의 컬럼을 이용해서 JOIN을 해주면 얼마든지 나이와 이름의 데이터를 가져올 수 있습니다.
이러한 이유로 관계형데이터베이스에서 JOIN을 사용하고 있으며 JOIN에는 어떤 종류가 있는지 아래에서 한가지씩 살펴보도록 하겠습니다.
참고로 LEFT JOIN과 INNER JOIN 이 두가지를 절대적으로 많이 사용하고 나머지는 사용빈도가 적은 편입니다.
게시글제목 | 게시글내용 | 작성자ID |
자기소개 | 중략... | zozo123 |
Join 사용법 | 중략... | zozo123 |
해외여행 후기 | 중략... | zozo123 |
ID | 나이 | 이름 |
zozo123 | 24 | 홍길동 |
sata3000 | 27 | 이순신 |
2. LEFT JOIN
첫번째로 살펴볼 JOIN은 LEFT JOIN입니다. 참고로 LEFT OUTER JOIN을 줄여쓰면 LEFT JOIN이 됩니다.
LEFT JOIN말고도 RIGHT JOIN도 있지만 사실상 LEFT JOIN과 방향만 다를 뿐 같은 개념이라고 생각하면 됩니다.
LEFT JOIN을 테스트 해보기 위해 아래의 테이블을 만들어 봤습니다.
게시판 샘플 테이블(bbs)
bbs_seq | title | description | id_seq |
1 | Oracle | Oracle is... | 1 |
2 | MySql | MySql is... | 1 |
3 | MariaDB | MariaDB is... | 2 |
4 | Cubrid | Cubrid is... | NULL |
아이디 샘플 테이블(id)
id_seq | id | name | profile_seq | |
1 | star23 | 홍길동 | 1 | |
2 | zozo11 | 이순신 | 2 | |
3 | haha600 | 강감찬 | 3 |
위에서 만든 테이블 두개를 이용하여 LEFT JOIN을 아래의 쿼리문처럼 실행해 봤습니다.
각 테이블의 id_seq컬럼을 이용하여 JOIN을 했고 LEFT JOIN이기 때문에 왼쪽에 위치한 ID테이블이 기준이 됩니다.
따라서 ID테이블에는 있지만 BBS에는 없는 데이터의 경우 ID테이블의 정보는 그대로 출력되고 B테이블의 컬럼들에는 NULL값이 들어간채로 출력이 됩니다.
SELECT * FROM BBS A
LEFT JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
bbs_seq | title | description | A.id_seq | B.id_seq | id | name | profile_seq |
1 | Oracle | Oracle is... | 1 | 1 | star23 | 홍길동 | 1 |
2 | MySql | MySql is... | 1 | 1 | star23 | 홍길동 | 1 |
3 | MariaDB | MariaDB is... | 2 | 2 | zozo11 | 이순신 | 2 |
4 | Cubrid | Cubrid is... | NULL | NULL | NULL | NULL | NULL |
이런식으로 JOIN후에 WHERE절로 조건을 줄수도 있습니다.
SELECT * FROM BBS A
LEFT JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
WHERE B.ID_SEQ IS NULL
bbs_seq | title | description | A.id_seq | B.id_seq | id | name | profile_seq |
4 | Cubrid | Cubrid is... | NULL | NULL | NULL | NULL | NULL |
3. INNER JOIN
두번째로 살펴볼 JOIN은 INNER JOIN입니다. 참고로 INNER JOIN은 NULL값이 없습니다.
JOIN하는 두 테이블 모두에서 존재하는 값만 출력되기 때문입니다.
LEFT JOIN에서 살펴봤던 예시의 테이블을 이용해서 INNER JOIN을 하면 다음과 같습니다.
아래는 맨위쪽에있는 샘플테이블을 참고하여 만든 쿼리문과 쿼리문에 대한 결과값입니다.
SELECT * FROM BBS A
INNDER JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
bbs_seq | title | description | A.id_seq | B.id_seq | id | name | profile_seq |
1 | Oracle | Oracle is... | 1 | 1 | star23 | 홍길동 | 1 |
2 | MySql | MySql is... | 1 | 1 | star23 | 홍길동 | 1 |
3 | MariaDB | MariaDB is... | 2 | 2 | zozo11 | 이순신 | 2 |
4. FULL OUTER JOIN
세번째로 살펴볼 JOIN은 FULL OUTER JOIN입니다.
참고로 FULL OUTER JOIN을 지원하지 않는 DB가 많습니다. FULL OUTER JOIN를 지원하지 않는 DB에서는 UNION 함수를 사용해서 FULL OUTER JOIN을 대체하여 사용합니다.
아래는 맨위쪽에있는 샘플테이블을 참고하여 만든 쿼리문과 쿼리문에 대한 결과값입니다.
SELECT * FROM BBS A
FULL OUTER JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
bbs_seq | title | description | A.id_seq | B.id_seq | id | name | profile_seq |
1 | Oracle | Oracle is... | 1 | 1 | star23 | 홍길동 | 1 |
2 | MySql | MySql is... | 1 | 1 | star23 | 홍길동 | 1 |
3 | MariaDB | MariaDB is... | 2 | 2 | zozo11 | 이순신 | 2 |
4 | Cubrid | Cubrid is... | NULL | NULL | NULL | NULL | NULL |
5 | NULL | NULL | NULL | 3 | haha600 | 강감찬 | 3 |
5. EXCLUSIVE JOIN
마지막으로 살펴볼 JOIN은 EXCLUSIVE JOIN입니다.
EXCLUSIVE JOIN는 만약 테이블 두개를 JOIN한다면 둘중 한가지 테이블에만 있는 데이터를 가져옵니다.
다른 JOIN들과는 다르게 별도의 EXCLUSIVE JOIN함수가 있는 것은 아니고 기존의 LEFT JOIN과 Where절의 조건을 함께 사용하여 만드는 JOIN입니다.
아래는 맨위쪽에있는 샘플테이블을 참고하여 만든 쿼리문과 쿼리문에 대한 결과값입니다.
SELECT * FROM BBS A
LEFT JOIN ID B
ON A.ID_SEQ = B.ID_SEQ
WHERE B.ID_SEQ IS NULL
bbs_seq | title | description | A.id_seq | B.id_seq | id | name | profile_seq |
4 | Cubrid | Cubrid is... | NULL | NULL | NULL | NULL | NULL |
댓글