본문 바로가기
Back-End/Database

[SQL] JOIN

by 찐코딩 2021. 10. 5.

join ~ on 키워드

테이블과 테이블을 연결하여 특정한 데이터를 얻고자 할 때 사용하는 키워드

두 개 이상의 테이블에 정보가 나뉘어져 있을 때 사용함

보통, 중복해서 데이터가 저장되는 것을 막기 위해 테이블을 나누어서 쓰게 됨
emp 테이블에서 부서의 상세정보까지 저장을 한다면 10번 부서에 소속된 사원이
3명이므로 부서원과 근무지가 3번 중복되어 나타남
이렇게 중복되어 저장된 데이터는 추후 삽입, 수정, 삭제 시 이상 현상이 발생할 수 있게 됨
즉, 이러한 현상이 발생하지 않게 하려면(= 데이터가 중복되어 저장되지 않게 하려면)
데이터베이스에서 두 개 이상의 테이블에 정보를 나우어서 저장해 두어야 함.
하지만 이렇게 두개의 테이블로 나누게 되면 데이터의 중복은 발생하지 않지만 원하는 정보를 얻으려면 
여러 번 질의를 해야하는 불편함이 발생함. 
특정 사원이 소속된 부서명을 알아내기 위해 emp 테이블과 dept테이블을 넘나드는 작업이 생김. 
따라서 두 개의 테이블을 결합해서 원하는 결과를 얻어낼 수 있도록 조인이라는 기능을 제공함.

 

조인의 종류

1) Cross Join
2) Equi Join
3) Self Join
4) Outer Join

 

Cross Join

두 개 이상의 테이블이 조인될 때 조건이 없이 테이블의 결합이 이루어지는 조인. 
그렇기 때문에 테이블 전체 행의 컬럼이 조인이 됨. 

 

 Equi Join 

- 가장 많이 사용되는 조인 방법. 
- 조인의 대상이 되는 두 테이블에서 공통적으로 존재하는 컬럼의 값이 일치되는 행을 연결하여 결과를 생성하는 방법. 
- 두 테이블이 조인하려면 일치되는 공통 컬럼을 사용하면 된다. 
- 컬럼의 이름이 같으면 혼동이 오기 때문에 컬럼명 앞에 테이블명을 기술해야 한다.

-- emp 테이블에서 사원의 사번, 이름, 담당업무, 부서번호, 부서명, 근무위치를 화면에 보여주세요
-- 부서명, 근무위치 emp 테이블에서 알 수 없음 ==> emp 테이블과 dept 테이블을 조인해주어야 함.
select empno, ename, job, e.deptno, dname, loc
from emp e join dept d	-- 테이블 명 정의(emp->e, dept->d)
on e.deptno = d.deptno;	-- 일치되는 공통 컬럼(=deptno), 컬럼명 앞에 테이블명(e/d)을 기술

 

-- emp 테이블에서 사원이 "SCOTT"인 사원의 부서명을 화면에 보여주세요
-- 이름, 부서번호, 부서명 입력
select e.ename, d.deptno, d.dname
from emp e join dept d	-- 테이블 명 정의(emp->e, dept->d)
on e.deptno = d.deptno	-- 일치되는 공통 컬럼(=deptno), 컬럼명 앞에 테이블명(e/d)을 기술
where e.ename='SCOTT';

 

-- [문제] emp 테이블에서 담당업무가 'MANAGER'인 사원의 이름과 담당업무, 부서번호
-- 부서명을 화면에 보여주세요
select ename, job, e.deptno, dname
from emp e join dept d
on e.deptno = d.deptno
where job='MANAGER';	--job은 emp 테이블에만 있으므로 따로 테이블명을 기재하지 않음

 

Self Join 

하나의 테이블 내에서 조인을 해야 자료를 얻을 수 있는데 자기 자신(SELF) 테이블과 조인을 맺는 것을 말함. 
FROM절 다음에 테이블명을 나란히 두 번 기술할 수 없음
따라서 같은 테이블이 하나 더 존재하는 것처럼 사용할 수 있도록 테이블에 별칭을 붙여서 사용.

-- emp 테이블에서 각 사원별 관리자의 이름을 화면에 출력해보자
-- 예) CLARK의 매니저 이름은 KING 입니다
select e1.ename || '의 매니저 이름은' || e2.ename || '입니다.' as " "
-- 같은 테이블이 하나 더 존재하는 것처럼 사용할 수 있도록 테이블에 별칭(e1/e2) 사용
from emp e1 join emp e2
on e1.mgr = e2.empno;	-- 관리자 번호(mgr)과 사번(empno)이 일치

하지만, emp테이블의 데이터 갯수는 14개인데 하나가 빠져있는 것을 볼 수 있다.

king은 매니저가 없어(mgr->null값) 출력이 안 되었다.

 

Outer 조인 

어느 한 쪽 테이블에는 해당하는 데이터가 다른쪽 테이블에는 존재하지 않는 경우, 그 데이터가 출력이 되지 않는 문제점을 해결하기 위해 사용되는 조인 기법. 
정보가 부족한 테이블의 컬럼 뒤에 '(+)'기호를 붙여서 사용함.

 

위에서 매니저가 없어 출력되지 않은 남은 데이터 하나까지 화면에 표시하고 싶다면 아래와 같이 쿼리문을 날리면 된다.

SELECT e1.ename || ' 의 매니저 이름은 ' || e2.ename || ' 입니다.'
FROM emp e1, emp e2
WHERE e1.mgr = e2.empno(+); -- NULL값도 포함하기 위해

 

--부서번호가 10, 20, 30, 40인 직원들의 이름, 부서번호, 부서이름을 화면에 띄우시오
select e.ename, d.deptno, d.dname
from emp e join dept d
on e.deptno(+) = d.deptno       -- 부서번호 40번 데이터가 없으므로
order by deptno;

emp 테이블에는 부서번호 40인 직원들이 없으므로 null값이 나타난다.

댓글