두 개 이상의 테이블을 공통 컬럼이나 특정 조건으로 연결해서 하나의 결과 테이블로 조회하는 방법
오라클 전용 JOIN과 ANSI JOIN(SQL 표준 문법) 두 가지가 있음
JOIN으로 테이블 별칭 사용 시 더 이상 테이블명을 사용할 수 없고 별칭만 사용 가능
2. 장점과 단점
1) 장점
정규화된 데이터를 조합해 한 번에 조회 가능
필요한 순간에만 테이블을 조합해 다양한 조회 가능
2) 단점
데이터가 많은 테이블을 JOIN하거나 많은 테이블을 JOIN하는 경우 성능 저하 발생
JOIN이 많아지면 쿼리가 복잡해져 유지보수 어려움
3) 단점 극복 방법
적절한 인덱스 생성
필요한 컬럼만 SELECT
작은 결과 데이터셋을 먼저 만들고 그 다음 조인하는 등 JOIN 순서 최적화
[ ERD 관계 표기 ]
표기
설명
실선
식별관계. 부모 ← 자식 관계로 부모 없으면 자식도 없음
점선
비식별관계. 부모 ← 자식 관계이나 부모 없이도 자식 있을 수 있음
[ 예시 테이블 ]
직원 테이블 EMPLOYEE
EMPLOYEE_ID
EMPLOYEE_NAME
DEPARTMENT_ID
MANAGER_ID
SALARY
1001
홍길동
10
NULL
3000
1002
김철수
20
1001
2500
1003
이영희
20
1001
2800
1004
박민수
NULL
1002
2200
1005
최지우
30
NULL
2600
부서 테이블 DEPARTMENT
DEPARTMENT_ID
DEPARTMENT_NAME
10
인사팀
20
개발팀
30
영업팀
40
총무팀
급여등급 테이블 SALARY_GRADE
GRADE_LEVEL
MIN_SALARY
MAX_SALARY
1
0
1999
2
2000
2499
3
2500
2999
4
3000
9999
[ ANSI JOIN ]
오라클 9i 버전부터 사용 가능 (SQL 표준 문법)
1. 조인 조건 : ON vs USING
구분
ON
USING
방식
조건을 직접 명시
같은 이름 컬럼으로 조인하는 축약 문법
컬럼명
달라도 됨
두 테이블에 같은 이름 컬럼이 있을 때만 가능
조인 키 출력
두 번 출력될 수 있음
한 번만 출력
-- ON
SELECT E.EMPLOYEE_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEE E
JOIN DEPARTMENT D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
-- USING
SELECT EMPLOYEE_NAME, DEPARTMENT_NAME
FROM EMPLOYEE
JOIN DEPARTMENT USING (DEPARTMENT_ID);
2. INNER JOIN (= JOIN)
ON 또는 USING 조건절 필수
보통 INNER는 생략하고 JOIN만 사용
조건에 맞는 행만 출력 (교집합)
SELECT *
FROM EMPLOYEE E
JOIN DEPARTMENT D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
EMPLOYEE_ID
EMPLOYEE_NAME
DEPARTMENT_ID
DEPARTMENT_NAME
1001
홍길동
10
인사팀
1002
김철수
20
개발팀
1003
이영희
20
개발팀
1005
최지우
30
영업팀
3. NATURAL JOIN
DB가 같은 이름의 컬럼을 자동으로 찾아 조인
잘못하면 여러 개 컬럼으로 조인될 수 있음
JOIN USING (공통컬럼 전부) 와 같은 효과
SELECT *
FROM EMPLOYEE
NATURAL JOIN DEPARTMENT;
DEPARTMENT_ID
EMPLOYEE_ID
EMPLOYEE_NAME
MANAGER_ID
SALARY
DEPARTMENT_NAME
10
1001
홍길동
NULL
3000
인사팀
20
1002
김철수
1001
2500
개발팀
20
1003
이영희
1001
2800
개발팀
30
1005
최지우
NULL
2600
영업팀
4. CROSS JOIN
카타시안 곱으로 모든 경우의 수 조합
결과 행 수 = A테이블 행 수 × B테이블 행 수
SELECT *
FROM EMPLOYEE
CROSS JOIN DEPARTMENT;
EMPLOYEE_ID
EMPLOYEE_NAME
DEPARTMENT_NAME
1001
홍길동
인사팀
1001
홍길동
개발팀
1001
홍길동
영업팀
1001
홍길동
총무팀
1002
김철수
인사팀
...
...
...
5. OUTER JOIN
JOIN 조건이 일치하지 않는 행도 출력
일치하지 않는 부분은 NULL로 표시
NULL 대신 다른 값을 넣으려면 COALESCE() 또는 CASE 사용
종류
기준 테이블
LEFT OUTER JOIN
FROM절 테이블 기준
RIGHT OUTER JOIN
JOIN절 테이블 기준
FULL OUTER JOIN
양쪽 모두 기준
-- LEFT OUTER JOIN (EMPLOYEE 기준, 부서 없는 직원도 출력)
SELECT E.EMPLOYEE_NAME,
D.DEPARTMENT_NAME
FROM EMPLOYEE E
LEFT JOIN DEPARTMENT D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
-- COALESCE로 NULL 대체
SELECT E.EMPLOYEE_NAME,
COALESCE(D.DEPARTMENT_NAME, '부서없음') AS DEPARTMENT_NAME
FROM EMPLOYEE E
LEFT JOIN DEPARTMENT D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
EMPLOYEE_NAME
DEPARTMENT_NAME
홍길동
인사팀
김철수
개발팀
이영희
개발팀
박민수
NULL
최지우
영업팀
EMPLOYEE_NAME
DEPARTMENT_NAME
홍길동
인사팀
김철수
개발팀
이영희
개발팀
박민수
부서없음
최지우
영업팀
여러 테이블 JOIN
SELECT E.EMPLOYEE_NAME,
D.DEPARTMENT_NAME,
S.GRADE_LEVEL
FROM EMPLOYEE E
JOIN DEPARTMENT D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
JOIN SALARY_GRADE S
ON E.SALARY BETWEEN S.MIN_SALARY AND S.MAX_SALARY;