분리된 테이블을 합쳐서 조회하는 문법이다.
테이블은 정규화라고 말하는 기법으로 분리시키는 경우가 잦다. 테이블 간의 중복된 데이터를 방지하며, 무결성을 유지할 수 있다. 정규화는 1~5까지 있는데 자세한 내용은 추후 설명하겠다.
EMPLOYEE 테이블에서 SMITH의 DNO를 보면 20인 것을 확인할 수 있다. 하지만. DNO(부서번호)만 알 수 있고, DNAME(부서이름)은 DEPARTMENT 테이블에 이동해야 확인할 수 있다. EMPLOYEE 테이블에서 DNAME을 확인하기 위해 DNO의 키를 추적해서 볼 수 있도록 JOIN을 쓰는 것이다.
JOIN을 쓰기 위한 조건으로는 특정 테이블의 기본키가 다른 테이블의 참조키로 들어와있어야한다.
간단하게 JOIN을 활용해보면, 출력이 EMPLOYEE 테이블과 DEPARTMENT 테이블이 옆으로 붙어져서 나오게 된다.
JOIN의 종류는 INNER JOIN(내부), OUTER JOIN(외부)이 있다. 위에서는 한꺼번에 출력해주는 EQUI JOIN(동등 / INNER JOIN)을 사용했다. EQUI JOIN을 사용하기 위해서는 기본키와 참조키의 관계 형성이 중요하다.
JOIN을 사용할 때 이렇게 이름이 중복되는 부분이 어느 테이블의 것인지 명시해주지 않으면 오류가 발생하니, 이 부분은 유의하는 것이 좋다.
사용하는 과정에서 테이블명이 길 경우 별칭을 사용하기도 한다. as는 생략가능하다.
- JOIN ~ ON
- EQUIP JOIN 이전에 쓰는 표준문법이다. 올드한 문법이라 요즘은 잘 쓰이진 않는다.
--1. scott 사원의 이름, 부서번호, 부서명 출력
select e.ename "사원명", e.dno "부서번호", d.dname "부서명" from employee e, department d
where e.dno = d.dno and e.eno=7788;
--2. 사원명, 부서명, 지역명 출력
select e.ename "사원명", d.dname "부서명", d.loc "지역명" from employee e, department d
where e.dno = d.dno;
--3. 이름에 'A'가 포함된 모든 사원의 이름, 부서명, 부서지역 출력
select e.ename "사원명", d.dname "부서명", d.loc "지역명" from employee e, department d
where e.dno = d.dno and e.ename like '%A%';
자동으로 중복된 컬럼을 제거하는 표준 문법이다. 아래와 같은 형식으로 사용할 수 있다.
select tabe1.column, table2column
from table1 NATURAL JOIN table2;
NATURAL JOIN에서는 자동으로 중복된 것을 제거해주기 때문에, e.dno 혹은 d.dno로 작성하면 오류가 발생한다. NATURAL JOIN을 쓸 때는 겹치는 부분은 편하게 작성해주면 된다.
- JOIN ~ USING
- JOIN ~ USING은 NATURAL JOIN과 같은 동작을 한다. 원래는 NATURAL JOIN이 표준이었는데 더 간결한 NATURAL JOIN을 이용하게 되었다.
EQUI JOIN과 Non-EQUI JOIN을 사용하여 3개 이상의 테이블에 JOIN하여 결과를 출력할 수도 있다.
OUTER JOIN(외부 조인)은 NULL 정보를 JOIN하면서 표시한다.
종류 | 설명 |
---|---|
LEFT OUTER JOIN | 왼쪽을 기준으로 NULL값이 존재 |
RIGHT OUTER JOIN | 오른쪽을 기준으로 NULL값이 존재 |
FULL OUTER JOIN | 양쪽 모두 조건이 일치하지 않는 경우까지 출력 |
--4. 커미션을 받을 수 있는 사원명, 부서명, 근무지 출력
select e.ename, d.dname, d.loc from employee e, department d
where e.dno=d.dno and e.commission > 0 order by e.ename;
--5. 뉴욕에 근무하는 모든 사원명, 업무, 부서번호, 부서명 출력
-- 부서번호 오름차순 정렬, 이름 내림차순 정렬
select e.ename "사원명", e.job "업무", d.dno "부서번호" , d.dname "부서명"
from employee e, department d
where e.dno = d.dno and d.loc = 'NEW YORK'
order by e.dno asc, e.ename desc;
--6. 사번, 사원명, 담당업무, 관리자번호, 부서번호, 부서명 출력 - left outer join
select e.eno "사번", e.ename "사원명", e.job "업무", e.manager "관리자번호", d.dno "부서번호" , d.dname "부서명"
from employee e left outer join department d on e.dno=d.dno;