데이터베이스 연구실.log

SELF JOIN

한 테이블을 별칭 두 개로 자기 자신과 조인해 사원과 관리자처럼 같은 테이블 안의 관계를 조회하는 SELF JOIN과, 실습용 emp, dept 재생성 스크립트

SELF JOIN테이블 별칭mgr관리자

#핵심 요약

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은 기존 테이블과 데이터를 지움

SQL Developer 또는 SQL*Plus (실습 스키마)데이터 또는 파일을 삭제함, 되돌릴 수 없음
ALTER SESSION SET nls_date_format = 'RR/MM/DD';
DROP TABLE emp;
DROP TABLE dept;
SQL Developer 또는 SQL*Plus (실습 스키마)객체 또는 설정을 변경함
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 샘플 데이터 형태임

#사원과 관리자

SQL Developer 또는 SQL*Plus조회만 함
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;

결과 해석: 두 번째는 관리자보다 월급이 많은 사원, 세 번째는 관리자보다 먼저 입사한 사원임

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기