SELF JOIN
한 테이블을 별칭 두 개로 자기 자신과 조인해 사원과 관리자처럼 같은 테이블 안의 관계를 조회하는 SELF JOIN과, 실습용 emp, dept 재생성 스크립트
#핵심 요약
self join은 자기 자신과 조인하는 문법임
같은 테이블을 FROM 절에 두 번 쓰고 서로 다른 별칭을 붙여, 조인 조건의 컬럼을 별칭으로 구분함
emp의 mgr(관리자의 사원번호)를 empno와 이으면 사원 이름과 직속 상사 이름을 한 행에 볼 수 있음
#개념과 동작 원리
"A self join is a join of a table to itself."
실습에서는 별칭을 사원, 관리자로 붙여 같은 emp를 두 역할로 나눴음
조인 조건 사원.mgr = 관리자.empno는 "사원 행의 관리자 번호가 관리자 행의 사원번호와 같다"는 뜻임
관리자가 없는 사원(mgr이 NULL인 KING)은 이 조건을 만족하지 않아 결과에서 빠짐(NULL 비교 규칙, NULL 처리)
모든 사원을 보려면 관리자 쪽을 outer join함
다만 (+)로는 테이블을 자기 자신과 outer join할 수 없다는 공식 문서 제약이 있어, ANSI LEFT OUTER JOIN을 씀(OUTER JOIN)
#필수 명령어 또는 SQL
#실습 테이블 재생성
실습에서는 실습 중 바뀐 emp, dept를 지우고 다시 만들었음DROP TABLE은 기존 테이블과 데이터를 지움
ALTER SESSION SET nls_date_format = 'RR/MM/DD';
DROP TABLE emp;
DROP TABLE dept;CREATE TABLE dept
( deptno NUMBER(10),
dname VARCHAR2(14),
loc VARCHAR2(13) );
INSERT INTO dept VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO dept VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO dept VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO dept VALUES (40, 'OPERATIONS', 'BOSTON');
CREATE TABLE emp
( empno NUMBER(4) NOT NULL,
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2) );
INSERT INTO emp VALUES (7839,'KING','PRESIDENT',NULL,'81-11-17',5000,NULL,10);
INSERT INTO emp VALUES (7698,'BLAKE','MANAGER',7839,'81-05-01',2850,NULL,30);
INSERT INTO emp VALUES (7782,'CLARK','MANAGER',7839,'81-05-09',2450,NULL,10);
INSERT INTO emp VALUES (7566,'JONES','MANAGER',7839,'81-04-01',2975,NULL,20);
INSERT INTO emp VALUES (7654,'MARTIN','SALESMAN',7698,'81-09-10',1250,1400,30);
INSERT INTO emp VALUES (7499,'ALLEN','SALESMAN',7698,'81-02-11',1600,300,30);
INSERT INTO emp VALUES (7844,'TURNER','SALESMAN',7698,'81-08-21',1500,0,30);
INSERT INTO emp VALUES (7900,'JAMES','CLERK',7698,'81-12-11',950,NULL,30);
INSERT INTO emp VALUES (7521,'WARD','SALESMAN',7698,'81-02-23',1250,500,30);
INSERT INTO emp VALUES (7902,'FORD','ANALYST',7566,'81-12-11',3000,NULL,20);
INSERT INTO emp VALUES (7369,'SMITH','CLERK',7902,'80-12-09',800,NULL,20);
INSERT INTO emp VALUES (7788,'SCOTT','ANALYST',7566,'82-12-22',3000,NULL,20);
INSERT INTO emp VALUES (7876,'ADAMS','CLERK',7788,'83-01-15',1100,NULL,20);
INSERT INTO emp VALUES (7934,'MILLER','CLERK',7782,'82-01-11',1300,NULL,10);
COMMIT;결과 해석:
실습에서는 입사일을 '81-11-17' 같은 문자열로 넣었음
세션 날짜 형식 RR/MM/DD에서 하이픈 구분 문자열이 날짜로 바뀐다는 전제임
이 데이터는 Oracle의 전통적인 SCOTT 샘플 데이터 형태임
#사원과 관리자
SELECT 사원.ename AS 사원이름, 관리자.ename AS 직속상사
FROM emp 사원, emp 관리자
WHERE 사원.mgr = 관리자.empno;
SELECT 사원.ename, 사원.sal, 관리자.ename, 관리자.sal
FROM emp 사원, emp 관리자
WHERE 사원.mgr = 관리자.empno
AND 사원.sal > 관리자.sal;
SELECT 사원.ename, 사원.hiredate, 관리자.ename, 관리자.hiredate
FROM emp 사원, emp 관리자
WHERE 사원.mgr = 관리자.empno
AND 사원.hiredate < 관리자.hiredate;결과 해석: 두 번째는 관리자보다 월급이 많은 사원, 세 번째는 관리자보다 먼저 입사한 사원임