Post

[DBP] CH1-1. Join

[DBP] CH1-1. Join

join

  • 하나 이상의 테이블을 연결하여 데이터를 검색하는 방법
    • 보통 두 개 이상의 행들의 공통된 값(기본키 및 외래키 값)을 사용하여 조인 실행
  • ex)
    1
    2
    3
    
      SELECT table.column1 [, table.column2, ...]
      FROM table1, table2
      WHERE table1.column1 = table2.column2;
    


Cartesian Product (카티션 곱)

  • 모든 가능한 행들의 조인으로, 검색하고자 했던 데이터뿐 아니라 조인에 사용된 테이블들의 모든 데이터 반환
  • 발생하는 경우
    • 조인 조건을 정의하지 않았을 경우 (Where 절 x)
    • 조인 조건이 잘못된 경우
    • 첫번째 테이블의 모든 행들이 두번째 테이블의 모든 행과 조인이 되는 경우


사원 번호와 사원 이름, 업무, 소속 부서명 출력

  • ex1) 조인 조건 명시 X
    1
    2
    
      SELECT empno, ename, job, dname
      FROM emp, dept;
    

    IMG_3F8FF17D5658-1

    • emp, dept 테이블의 모든 행 출력


  • ex2) 조인 조건 명시 O
    1
    2
    3
    
      SELECT empno, ename, job, dname
      FROM emp e, dept d
      WHERE e.empno > d.deptno;
    

    IMG_0BA443BF605B-1

    • empno는 7000번대, deptno는 10번대로 모든 튜플들이 조건 만족 -> 모든 행 출력


  • Cartesian Product
    = Cross Join
    = Cross Product
    1
    2
    3
    4
    5
    
      SELECT empno, ename, job, dname
      FROM emp, dept;
    
      SELECT empno, ename, job, dname
      FROM emp cross join dept;
    


Equi Join (동등 조인, 내부 조인)

  • 조인 조건에서 Equality Condition(=)을 사용하여 값들이 정확하게 일치하는 경우에 사용되는 조인
  • 대부분 기본키와 외래키 관계 이용
    1
    2
    3
    
      SELECT table.column1 [, table.column2, ...]
      FROM table1, table2
      WHERE table1.column1 = table2.column2;
    


  • ex) 급여가 2000 이상인 사원에 대해 사원 번호, 사원 이름, 업무, 부서명, 위치 검색
    1
    2
    3
    4
    
      SELECT empno, ename, job, dname, loc
      FROM emp, dept
      WHERE emp.deptno = dept.deptno 
      and sal >= 2000;
    
    1
    2
    3
    4
    
      SELECT empno, ename, job, dname, loc
      FROM emp inner join dept
      ON emp.deptno = dept.deptno 
      WHERE sal >= 2000;
    
    1
    2
    3
    4
    
      SELECT empno, ename, job, dname, loc
      FROM emp inner join dept
      USING (deptno)   
      WHERE sal >= 2000;
    
    EMPNOENAMEJOBDNAMELOC
    7782CLARKMANAGERACCOUNTINGNEW YORK
    7839KINGPRESIDENTACCOUNTINGNEW YORK
    7566JONESMANAGERRESEARCHDALLAS
    7902FORDANALYSTRESEARCHDALLAS
    7788SCOTTANALYSTRESEARCHDALLAS
    7698BLAKEMANAGERSALESCHICAGO
  • emp.deptno : 외래키, dept.deptno : 기본키
  • USING : 속성 이름이 같은 경우에만 사용 가능
    • () 없으면 에러
    • 속성명에 테이블명 명시 X
  • ON 조건절을 사용한 JOIN의 경우 ALIAS나 테이블 명과 같은 접두사를 사용하여 SELECT 에 사용되는 칼럼을 명확하게 지정해주어야 함


  • 다중 테이블 JOIN
1
2
3
4
5
6
SELECT E.EMPNO, D.DEPTNO, D.DNAME, T.DNAME New_DNAME 
FROM EMP E 
JOIN DEPT D 
ON (E.DEPTNO = D.DEPTNO) 
JOIN DEPT_TEMP T 
ON (E.DEPTNO = T.DEPTNO);


  • 테이블 별칭 (table alias) 이용
    • SELECT 문에서 유용
    • FROM 절에 별칭이 사용되면 SELECT 문 전체에서 사용 가능
      1
      2
      3
      
        SELECT empno, job, loc
        FROM emp e, dept d
        WHERE e.deptno = d.deptno;
      


Non-Equijoin

  • 테이블의 어떤 컬럼도 조인할 테이블의 칼럼에 일치하지 않는 경우에 사용
  • 조인 조건은 동등(=) 이외의 연산자 사용
    • BETWEEN AND, IS NULL, IS NOT NULL, IN, NOT IN 등
    • NOT 연산자, 크기 비교, NULL 등


  • ex) 급여가 3000과 4000 사이의 사원 이름과 부서명 출력
    1
    2
    3
    
      SELECT e.ename, d.dname
      FROM emp e, dept d
      WHERE e.sal BETWEEN 3000 AND 4000;
    
    ENAMEDNAME
    SCOTTACCOUNTING
    FORDACCOUNTING
    SCOTTRESEARCH
    FORDRESEARCH
    SCOTTSALES
    FORDSALES
    SCOTTOPERATIONS
    FORDOPERATIONS
    • 문제점) 카티션 곱에서 WHERE 조건 적용 -> 가짜 튜플 생성!
    • 이 예제의 경우 부서 번호를 비교하지 않아 WHERE 조건에 맞는 사원이 모든 부서에 연결되어 출력


Self Join

  • 자체적으로 테이블 조인하는 경우
  • ex) 각 사원의 관리자 출력 -> 둘 다 emp 테이블에 존재
    1
    2
    3
    
      SELECT e1.empno, e1.ename, e2.empno, e2.ename
      FROM emp e1, emp e2
      WHERE e1.mgr = e2.empno;
    
    EMPNOENAMEMGRNOMGRNAME
    7788SCOTT7566JONES
    7902FORD7566JONES
    7499ALLEN7698BLAKE
    7521WARD7698BLAKE
    7900JAMES7698BLAKE
    7844TURNER7698BLAKE
    7654MARTIN7698BLAKE
    7934MILLER7782CLARK
    7876ADAMS7788SCOTT
    7566JONES7839KING
    7782CLARK7839KING
    7698BLAKE7839KING
    7369SMITH7902FORD


Outer Join (외부 조인)

  • 정상적으로 조인 조건을 만족하지 못하는 행들을 보기 위해 사용
  • Equi Join은 조인하는 테이블의 두 개의 컬럼에서 공통된 값이 없다면 행을 반환하지 않음
  • 조인시킬 값이 없는 조인 측에 (+)
  • Outer Join 연산자는 표현식의 한 편에만 사용 가능 (왼 / 오 / full)


1
2
3
4
5
6
7
8
9
-- 왼쪽 Outer Join
SELECT table.column1 [, table.column2, ...]
FROM table1, table2
WHERE table1.column1 = table2.column2(+);

-- 오른쪽 Outer Join
SELECT table.column1 [, table.column2, ...]
FROM table1, table2
WHERE table1.column1(+) = table2.column2;


  • ex1) 일반 조인
    1
    2
    3
    
      SELECT DISTINCT(a.deptno), b.deptno
      FROM emp a, dept b
      WHERE a.deptno, b.deptno;
    
    DEPTNODEPTNO
    1010
    2020
    3030
    • 내부 조인 -> 조건에 해당되는 행들만 출력


  • ex2) Outer Join
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
      SELECT DISTINCT(a.deptno), b.deptno
      FROM emp a, dept b
      WHERE a.deptno(+) = b.deptno;
    
      -- 같은 표현
      SELECT a.deptno, b.deptno
      FROM emp a RIGHT OUTER JOIN dept b
      ON a.deptno = b.deptno;
    
      SELECT deptno, deptno
      FROM emp a RIGHT OUTER JOIN dept b
      USING <deptno>;
    
    DEPTNODEPTNO
    1010
    2020
    3030
     40
    • 오른쪽 조인 -> 오른쪽 테이블(dept table)의 모든 행 출력


  • ex3) full outer join은 양쪽에 (+)가 아니라, FULL OUTER JOIN 표현식 이용
    1
    2
    3
    4
    5
    6
    7
    
      SELECT deptno, deptno
      FROM emp a FULL OUTER JOIN dept b
      ON a.deptno = b.deptno;
    
      SELECT deptno, deptno
      FROM emp FULL OUTER JOIN dept
      USING <deptno>;
    
This post is licensed under CC BY 4.0 by the author.