우와한 개발자

[SQL] 조인(JOIN)이란? – INNER / NATURAL / CROSS / OUTER JOIN과 예시

by 우와한개발자

 

[ JOIN ]

1. JOIN이란?

  • 두 개 이상의 테이블을 공통 컬럼이나 특정 조건으로 연결해서 하나의 결과 테이블로 조회하는 방법
  • 오라클 전용 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;
EMPLOYEE_NAME DEPARTMENT_NAME GRADE_LEVEL
홍길동 인사팀 4
김철수 개발팀 3
이영희 개발팀 3
최지우 영업팀 3

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기