ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 8. JOIN : 여러 테이블을 하나의 테이블처럼 사용하자
    Oracle 2023. 8. 21. 16:13

    8.0. 표준 SQL과 ORACLE(기존)에서 JOIN 활용

    • 표준 SQL JOIN(권장)
    SELECT ENAME, JOB, SAL, DNAME, LOC
    FROM EMP INNER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    • ORACLE JOIN
    SELECT ENAME, JOB, SAL, DNAME, LOC
    FROM EMP, DEPT
    WHERE EMP.DEPTNO = DEPT.DEPTNO;

    기존 방식의 ORACLE JOIN을 여전히 활용하는 곳이 많다. 백엔드에서는 구 문법을 그대로 사용하는 경우가 많지만, 너무 오래된 문법이라 바꾸길 권장한다고.

     

    8.1. 표준 SQL 조인

    8.1.1. 조인의 조건 : 공통의 열

    1. 같은 종류의 데이터 타입(값이 같을 필요는 없음)
    2. 값의 범위가 일치

     

    8.1.2. 조인의 종류

    • NATURAL JOIN(사용하지 않음)
    • INNER JOIN(내부 조인)
    • OUTER JOIN(외부 조인)
    • CROSS JOIN(사용할 일이 별로 없다)

       8.1.2.1 NATURAL JOIN

    SELECT ENAME, JOB, SAL, DNAME, LOC
    FROM EMP NATURAL JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    간결한 문장으로 사용가능한 NATURAL JOIN!

    • 사용해서는 안 되는 이유
      • 결합 조건이 명시적으로 보이지 않아, 이해와 유지 보수가 어렵다.
      • 예측이 어렵다. 열 이름, 또는 열 위치에 따라 결합시킨다. 이에 쿼리의 결과를 예측하기 어려우며, 테이블 구조가 변경될 때 예기치 않은 결과가 발생할 가능성이 크다.

       8.1.3. INNER JOIN : JOIN에 조건을 만족하지 못 하는 행은 JOIN에 참여할 수 없다.

    SELECT *
    FROM EMP INNER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    DEPTNO가 40인 행은 EMP 테이블에 없다. 이에 위 사진에서 DEPTNO가 40인 행은 JOIN에 참여하지 못 했다.

    • JOIN의 조건을 명시하는 다른 방법
      • USING(사용하지 않음) : 공통의 컬럼명을 기준으로 조인. 그러나 서로 이름이 다른 경우 조인이 안 됨. (=)연산 외에 다른 연산을 수행할 수 없음.
    SELECT ENAME, JOB, SAL, DNAME, LOC
    FROM EMP INNER JOIN DEPT
    	 USING (DEPTNO);

    SELECT ENAME, JOB, SAL, DEPTNO
    FROM EMP INNER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    DEPTNO가 양쪽 테이블에 다 존재. 어떤 테이블의 DEPTNO의 값을 SELECT 했는지 ambiguously 애매하다고 오류가 뜬다.

    SELECT ENAME, JOB, SAL, DEPT.DEPTNO
    FROM EMP INNER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    DEPT 테이블의 DEPTNO을 표시하고 있다.

    • TABLE ALIAS
    SELECT EMP.ENAME, EMP.JOB, EMP.SAL, EMP.HIREDATE, DEPT.DEPTNO, DEPT.DNAME, DEPT.LOC
    FROM EMP INNER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    라고 코드를 쓰면 너무 길고 귀찮다. 이 때 테이블 별칭을 활용할 수 있다.

    SELECT E.ENAME, E.JOB, E.SAL, E.HIREDATE, D.DEPTNO, D.DNAME, D.LOC
    FROM EMP E INNER JOIN DEPT D
    	 ON E.DEPTNO = D.DEPTNO;

    출력 결과에는 테이블 별칭이 표시되지 않는다.

    • Equi JOIN : = 연산자를 이용한 조인 방법
    • Non Equi JOIN : = 연산자 이외의 방법을 이용한 조인 방법
    SELECT * FROM SALGRADE;

    SELECT ENAME, JOB, SAL, GRADE
    FROM EMP INNER JOIN SALGRADE
    	 ON SAL BETWEEN LOSAL AND HISAL;

    • Self JOIN : 하나의 테이블 안에 공통의 컬럼을 가질 경우(자기참조 테이블, 재귀적 테이블) Self JOIN을 수행할 수 있다
    SELECT WORKER.ENAME, WORKER.MGR, MANAGER.EMPNO, MANAGER.ENAME
    FROM EMP WORKER INNER JOIN EMP MANAGER
    	 ON WORKER.MGR = MANAGER.EMPNO;

    SELECT WORKER.ENAME || '의 관리자는 ' || MANAGER.ENAME || '이다' AS "사원과 관리자"
    FROM EMP WORKER INNER JOIN EMP MANAGER
    	 ON WORKER.MGR = MANAGER.EMPNO;

    Self JOIN을 쓸 때는 반드시

    1. TABLE ALIAS를 써야 한다.
    2. 모든 컬럼명 앞에는 ALIAS를 써줘야 한다.

     

    8.1.4 OUTER JOIN : 조건을 만족하지 못하는 행도 JOIN에 참여할 수 있다

    OUTER JOIN 종류

    • LEFT OUTER JOIN
    • RIGHT OUTER JOIN
    • FULL OUTER JOIN

     

    KIMHUGO 사원을 EMP 테이블에 추가해보자

    INSERT INTO EMP (EMPNO, ENAME, JOB, SAL, DEPTNO)
    VALUES (9999, 'KIMHUGO', 'CLERK', 1250, NULL);

    SELECT ENAME, JOB, SAL, DNAME
    FROM EMP INNER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    그러나 부서번호가 존재하지 않는 김휴고 사원은 JOIN에 참여할 수 없다

    SELECT ENAME, JOB, SAL, DNAME
    FROM EMP LEFT OUTER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    LEFT OUTER JOIN을 통해 EMP 테이블에서 김휴고 사원을 조인에 참여시켰다. 단, 부서 정보는 NULL

    SELECT ENAME, JOB, SAL, DNAME
    FROM EMP RIGHT OUTER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    DEPT 테이블에서 JOIN에 참여하지 못했던 'OPERATIONS'행이 조인에 참여하게 되었다.

    SELECT ENAME, JOB, SAL, DNAME
    FROM EMP FULL OUTER JOIN DEPT
    	 ON EMP.DEPTNO = DEPT.DEPTNO;

    OUTER JOIN 양쪽 모두의 테이블에서 JOIN 조건을 참여하지 못했던 행들도 출력되었다.

     

    8.1.5 CROSS JOIN : JOIN의 조건이 없어요! 그냥 없어요!

    SELECT *
    FROM EMP CROSS JOIN DEPT;

    워워
    진정하라구. 친구.

    CROSS JOIN은 조건이 없고(암묵적으로 만들지도 않음) 어떻게 두 테이블을 합쳐야 할 지도 모르므로,

    연결 가능한 모든 조합을 출력함.

     

    8.1.6. Multi-table JOIN : JOIN은 항상 두 테이블 간에. 그렇다면 여러 테이블을 조인하려면?

    ((((A JOIN B) JOIN C) JOIN D) JOIN E)

    SELECT ENAME, JOB, SAL, GRADE, DNAME
    FROM EMP INNER JOIN SALGRADE ON SAL BETWEEN LOSAL AND HISAL
    	     INNER JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO;

Designed by Tistory.