1. 조인
1) 데카르트 곱
SELECT C.FIRST_NAME, C.LAST_NAME, A.ADDRESS
FROM CUSTOMER C
JOIN ADDRESS A
→ 두 테이블을 어떻게 조인할 지 지정해주지 않았기 때문에 서버가 교차조인(고객 599명 X 주소 603개) 해버림
2) 내부조인
- 한 쪽 테이블에는 ADDRESS_ID가 있지만 다른 한 쪽에는 없는 경우는 결과 값에서 제외됨
SELECT C.FIRST_NAME, C.LAST_NAME, A.ADDRESS FROM CUSTOMER C INNER JOIN ADDRESS A ON C.ADDRESS_ID = A.ADDRESS_ID;
3) ANSI문법
-- 기존
SELECT C.FIRST_NAME, C.LAST_NAME, A.ADDRESS
FROM CUSTOMER C, ADDRESS A
WHERE C.ADDRESS_ID = A.ADDRESS_ID;
SELECT C.FIRST_NAME, C.LAST_NAME, A.ADDRESS
FROM CUSTOMER C, ADDRESS A
WHERE C.ADDRESS_ID = A.ADDRESS_ID
AND A.POSTAL_CODE = 52137;
-- 쿼리문이 길어지고 복잡해수록 어떤 것이 조인 조건이고, 어떤 것이 WHERE절의 조건인지 구분하기 힘들어지며 누락하기도 쉬워짐
SELECT C.FIRST_NAME, C.LAST_NAME, A.ADDRESS
FROM CUSTOMER C
INNER JOIN ADDRESS A
ON C.ADDRESS_ID = A.ADDRESS_ID
WHERE A.POSTAL_CODE = 52137;
2. 3개 이상의 테이블 조인
- From절에서 테이블을 나열하는 순서는 중요하지 않음
SELECT C.FIRST_NAME, C.LAST_NAME, CT.CITY
FROM CUSTOMER C
INNER JOIN ADDRESS A
ON C.ADDRESS_ID = A.ADDRESS_ID
INNER JOIN CITY CT
ON CA.CITY_ID = CT.CITY_ID;
SELECT C.FIRTST_NAME, C.LAST_NAME, CT.CITY
FROM CITY CT
INNER JOIN ADDRESS A
ON A.CITY_ID = CT.CITY_ID
INNER JOIN CUSTOMER C
ON A.ADDRESS_ID = C.ADDRESS_ID;
SELECT C.FIRST_NAME, C.LAST_NAME, CT.CITY
FROM ADDRESS A
INNER JOIN CITY CT
ON A.CITY_ID = C.CITY_ID
INNER JOIN CUSTOMER C
ON C.ADDRESS_ID = A.ADDRESS_ID;
- 3개의 쿼리문의 결과는 다 동일
1) 서브쿼리 사용
SELECT C.FIRST_NAME, C.LAST_NAME, ADDR.ADDRESS, ADDR.CITY
FROM CUSTOMER C
INNER JOIN ( SELECT A.ADDRESS_ID, A.ADDRESS, CT.CITY
FROM ADDRESS A
INNER JOIN CITY CT
ON A.CITY_ID = A.CITY_ID
WHERE A.DISTRICT = 'CALIFORNIA') ADDR
ON C.ADDRESS_ID = ADDR.ADDRESS_ID;
2) 테이블 재사용하기
- 같은 테이블을 여러번 조인해야 하는 경우가 있는데 아래와 같이 사용할 수 있다.
SELECT F.TITLE
FROM FILM F
INNER JOIN FILM_ACTOR FA
ON F.FILM_ID = FA.FILM_ID
INNER JOIN ACTOR A
ON FA.ACTOR_ID = A.ACTOR_ID
WHERE((A.FIRST_NAME = 'CATE' AND A.LAST_NAME = 'MCQUEEN')
OR (A.FIRST_NAME = 'CUBA' AND A.LAST_NAME = 'BIRCH')
);
3. 셀프조인
- 쿼리에 동일한 테이블을 한 번 이상 포함할 수 있을 뿐 아니라 테이블을 자기자신과 조인할 수도 있음
- 자기참조 외래키를 가질 경우
-- FILM테이블에 PREQUEL_FILM_ID라는 컬럼이 포함되어 있다고 가정
SELECT F.TITLE, F_PRNT.TITLE PREQUEL
FROM FILM F
INNER JOIN FILM F_PRNT
ON F_PRNT.FILM_ID = F.PREQUEL_FILM_ID
WHERE F.PREQUEL_FILM_ID IS NOT NULL;
-- 외래키 PREQUEL_FILM_ID를 사용해서 셀프 조인