OUTER JOIN은 SQL에서 두 테이블 간의 관계를 설정할 때, 한쪽 테이블에만 데이터가 있는 경우에도 모든 행을 포함할 수 있도록 도와주는 조인 방식입니다. INNER JOIN과 달리, 일치하지 않는 데이터도 함께 조회할 수 있는 것이 큰 특징입니다.
LEFT OUTER JOIN은 왼쪽 테이블의 모든 행을 유지하고, 오른쪽 테이블에서 일치하는 데이터만 가져옵니다. 일치하지 않는 오른쪽 테이블의 데이터는 NULL
로 표시됩니다.
SELECT 열_목록
FROM 테이블1
LEFT JOIN 테이블2 ON 테이블1.공통_열 = 테이블2.공통_열;
RIGHT OUTER JOIN은 오른쪽 테이블의 모든 행을 유지하고, 왼쪽 테이블에서 일치하는 데이터만 가져옵니다. 일치하지 않는 왼쪽 테이블의 데이터는 NULL
로 표시됩니다. 예를 들어, 모든 부서와 해당 부서의 직원 목록을 확인하고자 할 때 사용합니다. 부서에는 직원이 없을 수도 있습니다.
SELECT 열_목록
FROM 테이블1
RIGHT JOIN 테이블2 ON 테이블1.공통_열 = 테이블2.공통_열;
-- 모든 부서와 해당 부서에 속한 직원 정보 가져오기. 직원이 없는 부서도 포함
SELECT d.deptno, e.empno, e.ename, d.dname
FROM emp e
RIGHT JOIN dept d ON e.deptno = d.deptno;
+--------+-------+--------+------------+
| deptno | empno | ename | dname |
+--------+-------+--------+------------+
| 10 | 7782 | CLARK | ACCOUNTING |
| 10 | 7839 | KING | ACCOUNTING |
| 10 | 7934 | MILLER | ACCOUNTING |
| 20 | 7369 | SMITH | RESEARCH |
| 20 | 7566 | JONES | RESEARCH |
| 20 | 7788 | SCOTT | RESEARCH |
| 20 | 7876 | ADAMS | RESEARCH |
| 20 | 7902 | FORD | RESEARCH |
| 30 | 7499 | ALLEN | SALES |
| 30 | 7521 | WARD | SALES |
| 30 | 7654 | MARTIN | SALES |
| 30 | 7698 | BLAKE | SALES |
| 30 | 7844 | TURNER | SALES |
| 30 | 7900 | JAMES | SALES |
| 40 | NULL | NULL | OPERATIONS |
+--------+-------+--------+------------+
-- 사원이 없는 부서 찾기
select d.deptno, d.dname, e.empno, e.ename
from emp e right outer join dept d
on d.deptno = e.deptno;
where e.ename is null;
+--------+------------+-------+-------+
| deptno | dname | empno | ename |
+--------+------------+-------+-------+
| 40 | OPERATIONS | NULL | NULL |
+--------+------------+-------+-------+
SELF JOIN은 하나의 테이블을 스스로 조인하여 동일 테이블 내의 데이터를 결합할 때 사용하는 조인 방식입니다. SELF JOIN은 일반적으로 테이블 내의 두 행 간의 관계를 비교하거나, 계층 구조(예: 직원과 상사 관계)를 나타낼 때 유용합니다.
SELF JOIN은 같은 테이블에서 두 개의 서로 다른 행을 조인하는 방식입니다. 여기서는 직원과 상사 간의 관계를 나타내기 위해 같은 테이블을 두 번 참조합니다.
SELECT 별칭1.열_목록, 별칭2.열_목록
FROM 테이블명 별칭1
JOIN 테이블명 별칭2 ON 별칭1.공통_열 = 별칭2.공통_열;
SELF JOIN을 사용하여 직원과 상사 관계 표시
SELECT e.empno AS 직원번호, e.ename AS 직원이름, m.empno AS 상사번호, m.ename AS 상사이름
FROM emp e
LEFT JOIN emp m ON e.mgr = m.empno;
+--------------+--------------+--------------+--------------+
| 직원번호 | 직원이름 | 상사번호 | 상사이름 |
+--------------+--------------+--------------+--------------+
| 7369 | SMITH | 7902 | FORD |
| 7499 | ALLEN | 7698 | BLAKE |
| 7521 | WARD | 7698 | BLAKE |
| 7566 | JONES | 7839 | KING |
| 7654 | MARTIN | 7698 | BLAKE |
| 7698 | BLAKE | 7839 | KING |
| 7782 | CLARK | 7839 | KING |
| 7788 | SCOTT | 7566 | JONES |
| 7839 | KING | NULL | NULL |
| 7844 | TURNER | 7698 | BLAKE |
| 7876 | ADAMS | 7788 | SCOTT |
| 7900 | JAMES | 7698 | BLAKE |
| 7902 | FORD | 7566 | JONES |
| 7934 | MILLER | 7782 | CLARK |
+--------------+--------------+--------------+--------------+
emp
테이블을 e
와 m
으로 나누어 사용했습니다.e.mgr = m.empno
조건을 사용하여 각 직원의 상사 정보를 연결합니다.LEFT JOIN
을 사용하여 상사가 없는 직원의 정보도 함께 조회합니다. (예: mgr
이 NULL인 최고 경영자)* 계층 구조 표현: 직원과 상사 관계, 부서와 상위 부서 간의 관계 등.
* 두 행 간 비교: 같은 테이블에서 두 열을 서로 비교해야 할 때 사용.
* 특정 기준의 상호 비교: 날짜 차이 계산, 중복 데이터 식별 등 특정 기준에 따라 비교해야 하는 경우.
[문제] 사원번호, 사원이름, 관리자 이름을 출력 (관리자가 없으면 '관리자 없음'으로 출력)
결과
+--------------+--------------+------------------+
| 사원번호 | 사원이름 | 관리자이름 |
+--------------+--------------+------------------+
| 7369 | SMITH | FORD |
| 7499 | ALLEN | BLAKE |
| 7521 | WARD | BLAKE |
| 7566 | JONES | KING |
| 7654 | MARTIN | BLAKE |
| 7698 | BLAKE | KING |
| 7782 | CLARK | KING |
| 7788 | SCOTT | JONES |
| 7839 | KING | 관리자 없음 |
| 7844 | TURNER | BLAKE |
| 7876 | ADAMS | SCOTT |
| 7900 | JAMES | BLAKE |
| 7902 | FORD | JONES |
| 7934 | MILLER | CLARK |
+--------------+--------------+------------------+
SELECT e.empno AS 사원번호, e.ename AS 사원이름,
IFNULL(m.ename, '관리자 없음') AS 관리자이름
FROM emp e
LEFT JOIN emp m ON e.mgr = m.empno;