조인이란?
두개 이상의 테이블이나 데이터베이스를 연결하여 데이터를 검색하는 방법이다. 자신이 검색하고 싶은 컬럼이 다른 테이블에 있을 경우 주로 사용하며 여러 개의 테이블을 마치 하나의 테이블인 것처럼 활용하는 방법이다. 보통 Primary key혹은 Foreign key로 두 테이블을 연결한다. 테이블을 연결하려면 적어도 하나의 컬럼은 서로 공유되고 있어야 한다.
조인의 종류
- INNER JOIN
- LEFT OUTER JOIN
- RIGHT OUTER JOIN
- FULL OUTER JOIN
- CROSS JOIN
- SELF JOIN
SQL 조인 쉽게 이해하기 위한 다이어그램
그렇다면, 이제 다음과 같은 테이블 두 개를 가지고 각각의 조인에 대해 알아보자.
[Star 테이블]
ID | Name | DepNo |
1 | 강호동 | 10 |
2 | 이수근 | 10 |
3 | 유재석 | 20 |
4 | 박명수 | 20 |
5 | 안재현 | 30 |
6 | 송민호 | 30 |
7 | 이병헌 | NULL |
[Dep 테이블]
DepNo | DepName |
10 | 1박2일 |
20 | 무한도전 |
30 | 신서유기 |
40 | 이경규가간다 |
INNER JOIN
쉽게말해 교집합이라고 생각하면 된다. 기준 테이블과 Join 테이블의 중복된 값을 보여준다.
가장 일반적인 조인으로, 조인 사용시 명령어로 INNER JOIN 대신 JOIN 만을 입력해도 INNER JOIN이 사용된다.
결과값은 A의 테이블과 B테이블이 모두 가지고 있는 데이터만 검색된다.
--문법--
SELECT
테이블별칭.조회할칼럼,
테이블별칭.조회할칼럼
FROM 기준테이블 별칭
INNER JOIN 조인테이블 별칭 ON 기준테이블별칭.기준키 = 조인테이블별칭.기준키...
--예제--
SELECT Star.Name, Dep.DepName
From Star
INNER JOIN Dep ON Star.DepNo = Dep.DepNo
위의 Star, Dep 테이블을 가지고 INNER JOIN 을 수행한 결과는 다음과 같다.
Name | DepName |
강호동 | 1박2일 |
이수근 | 1박2일 |
유재석 | 무한도전 |
박명수 | 무한도전 |
안재현 | 신서유기 |
송민호 | 신서유기 |
Star테이블과 Dep테이블 중에서 Star의 DepNo와 Dep의 DepNo가 일치하는 요소들만 골라서 출력을 하게된다.
여기서 눈여겨 보아야 할 부분은, Star테이블의 '이병헌'과 Dep테이블의 '이경규가 간다' 라는 행이 누락되어 있는 것이다.
이 둘은 두 테이블 간의 공통된 데이터가 없기 때문이다.
즉, '이병헌'은 DepNo가 Null이기 때문에 Dep테이블과 겹치는 부분이 없으며 '이경규가간다' 는 Star테이블에서 같은 DepNo 코드를 가진 데이터가 없기 때문에 출력되지 않은 것이다.
이렇듯, INNER JOIN은 ON의 조건에 맞는 공통된 부분이 있는 경우에만 출력이 된다
위의 INNER JOIN은 공통된 부분이 있는 행만 출력을 해주었는데, 공통된 부분이 없는 데이터도 함께 보고싶은 경우가 있을 것이다.
이럴 때 사용하는 것이 바로 OUTER JOIN이다
LEFT OUTER JOIN
기준 테이블의 값 + 조인 테이블의 값을 보여준다.
왼쪽 테이블을 기준으로 JOIN을 하겠다고 생각하면 된다.
그럼 결과값은 A테이블의 모든 데이터와 A테이블과 B테이블의 중복되는 값이 검색된다.
--문법--
SELECT
테이블별칭.조회할칼럼,
테이블별칭.조회할칼럼
FROM 기준테이블 별칭
LEFT OUTER JOIN 조인테이블 별칭 ON 기준테이블별칭.기준키 = 조인테이블별칭.기준키...
SELECT Star.Name, Dep.Name
FROM Star
LEFT OUTER JOIN Dep ON Star.DepNo = Dep.DepNo
위의 쿼리를 실행한 결과는 다음과 같다.
Name | DepName |
강호동 | 1박2일 |
이수근 | 1박2일 |
유재석 | 무한도전 |
박명수 | 무한도전 |
안재현 | 신서유기 |
송민호 | 신서유기 |
이병헌 | NULL |
공통된 값 + 왼쪽 테이블에만 있는 값이 출력된 것을 알 수 있다.
반면, 여기서 만약 공통된 부분마저 제외하고 왼쪽에 '만' 있는 것을 출력하고 싶다면
다음과 같이 NULL을 이용하여 한 가지 조건만 더 추가해주면 된다.
SELECT Star.Name, Dep.Name
From Star
LEFT OUTER JOIN Dep ON Star.DepNo = Dep.DepNo
WHERE Star.DepNo IS NULL
위 쿼리를 실행한 결과는 다음과 같다.
Name | DepName |
이병헌 | Null |
RIGHT OUTER JOIN
LEFT OUTER JOIN의 반대로 오른쪽 테이블을 기준으로 JOIN을 하겠다는 것이다.
그럼 결과값은 B테이블의 모든 데이터와 A테이블과 B테이블의 중복되는 값이 검색된다.
--문법--
SELECT
테이블별칭.조회할칼럼,
테이블별칭.조회할칼럼
FROM 기준테이블 별칭
RIGHT OUTER JOIN 조인테이블 별칭 ON 기준테이블별칭.기준키 = 조인테이블별칭.기준키...
--예제--
SELECT Star.Name, Dep.Name
FROM Star
RIGHT OUTER JOIN Dep ON Star.DepNo = Dep.DepNo
위 쿼리를 실행한 결과는 다음과 같다.
Name | DepName |
강호동 | 1박2일 |
이수근 | 1박2일 |
유재석 | 무한도전 |
박명수 | 무한도전 |
안재현 | 신서유기 |
송민호 | 신서유기 |
NULL | 이경규가간다 |
여기서, 위의 LEFT JOIN과 마찬가지로 RIGHT 테이블에 '만' 있는 것을 출력하고 싶다면
똑같이 NULL 속성을 이용하여 출력할 수 있다. (위의 LEFT JOIN 설명 참고)
FULL OUTER JOIN
쉽게 말해 합집합을 생각하면 된다. A테이블이 가지고 있는 데이터 , B테이블이 가지고 있는 모든 데이터가 검색된다.
사실상 기준테이블의 의미가 없다.
--문법--
SELECT
테이블별칭.조회할칼럼,
테이블별칭.조회할칼럼
FROM 기준테이블 별칭
FULL OUTER JOIN 조인테이블 별칭 ON 기준테이블별칭.기준키 = 조인테이블별칭.기준키...
--예제--
SELECT Star.Name, Dep.Name
FROM Star
FULL OUTER JOIN Dep ON Star.DepNo = Dep.DepNo
위 쿼리를 실행한 결과는 다음과 같다.
Name | DepName |
강호동 | 1박2일 |
이수근 | 1박2일 |
유재석 | 무한도전 |
박명수 | 무한도전 |
안재현 | 신서유기 |
송민호 | 신서유기 |
이병헌 | NULL |
NULL | 이경규가간다 |
즉, LEFT OUTER JOIN과 RIGHT OUTER JOIN의 결과값을 합친 것이라고 볼 수 있다.
※ MySQL에서는 FULL OUTER JOIN을 지원하지 않는다. 하지만 OUTER JOIN과 UNION을 이용하면 FULL OUTER JOIN을 할 수 있다.
select star.name, dep.depname
from star left join dep on star.DepNo=dep.DepNo
union
select star.name, dep.depname
from star right join dep on star.DepNo=dep.DepNo;
CROSS JOIN
크로스 조인은 모든 경우의 수를 전부 표현해주는 방식이다.
기준 테이블이 A일 경우 A의 데이터 한 ROW를 B테이블 전체와 JOIN 하는 방식이다.
즉, 카디널리티 곱을 한 것이다.
그래서 결과값도 N * M 가 된다.
위 사진에서는 A테이블에 데이터가 3개, B테이블에는 데이터가 4개가 있으므로 총 12개가 검색된다.
--문법(첫번째방식)--
SELECT
테이블별칭.조회할칼럼,
테이블별칭.조회할칼럼
FROM 기준테이블 별칭
CROSS JOIN 조인테이블 별칭
--예제(첫번째방식)--
SELECT Star.Name, Dep.DepName
FROM Star
CROSS JOIN Dep
======================================================================
--문법(두번째방식)--
SELECT
테이블별칭.조회할칼럼,
테이블별칭.조회할칼럼
FROM 기준테이블 별칭,조인테이블 별칭
--예제(두번째방식)--
SELECT Star.Name, Dep.DepName
FROM Star, Dep;
위 쿼리를 실행한 결과는 다음과 같다.
Name | DepName |
강호동 | 1박2일 |
이수근 | 1박2일 |
유재석 | 1박2일 |
박명수 | 1박2일 |
안재현 | 1박2일 |
송민호 | 1박2일 |
이병헌 | 1박2일 |
강호동 | 무한도전 |
이수근 | 무한도전 |
... | ... |
송민호 | 이경규가간다 |
이병헌 | 이경규가간다 |
위의 결과 처럼, 두 테이블의 모든 행들을 서로 교차하여 곱한다고 생각하면 된다.
그래서 Star테이블(7행) x Dep테이블(4행) = 28 행이 탄생하게 된다.
SELF JOIN
셀프 조인은 자기자신과 자기 자신을 조인한다는 의미다.
하나의 테이블을 여러번 복사해서 조인한다고 생각하면 편하다.
자신이 가지고 있는 컬럼을 다양하게 변형시켜 활용할 경우에 자주 사용한다.
SELF JOIN이 필요한 상황은 다음과 같다.
[A 테이블]
ID | Name | Partner |
1 | 강호동 | 3 |
2 | 유재석 | 4 |
3 | 나영석 | 5 |
4 | 김태호 | 6 |
5 | 이명한 | 1 |
6 | 박명수 | 2 |
위의 A 테이블을 보면 각각의 스타의 ID와 이름, Partner의 번호가 부여되어 있다.
이 때, Partner의 번호 대신 이름을 알고 싶다면 어떻게 해야 할까?
이때 SELF JOIN을 이용하면 이름을 알 수 있다.
Partner의 정보도 같은 테이블 내에 존재하기 때문이다.
이렇게 Self 조인 쿼리를 작성해보자.
--문법--
SELECT
테이블별칭.조회할칼럼,
테이블별칭.조회할칼럼
FROM 테이블 별칭,테이블 별칭2
--예제--
SELECT A.ID, A.Name, A.Partner, B.Partner PartName
FROM Star A JOIN Star B
ON A.Partner = B.ID
위 쿼리를 실행한 결과는 다음과 같다.
ID | Name | Partner | PartName |
1 | 강호동 | 3 | 나영석 |
2 | 유재석 | 4 | 김태호 |
3 | 나영석 | 5 | 이명한 |
4 | 김태호 | 6 | 박명수 |
5 | 이명한 | 1 | 강호동 |
6 | 박명수 | 2 | 유재석 |
이렇게 하나의 테이블을 가지고 SELF JOIN을 이용하여 원하는 값을 출력할 수 있다.
정리
데이터베이스는 개발직 면접에서 자주 등장하는 단골 분야이다.
따라서, 다음과 같은 질문에 답을 할 수 있도록 미리 준비해보는 것도 추천한다.
- JOIN의 종류와 각각의 종류의 특징에 대해 이야기 해보세요
- SELF 조인을 사용할 경우를 예를 들어 보세요
- LEFT OUTER JOIN을 수행할 때, 오직 LEFT에만 있는 값을 가져오도록 쿼리를 한번 짜보세요.
- left outer join, inner join 차이를 설명해 주세요
참고