본문 바로가기
IT/DataBase

SQL - JOIN

by 천빈 2021. 5. 24.

JOIN

  • DB에서 여러 테이블의 데이터가 필요한 경우 사용된다
  • 어떤 테이블을 기준으로 다른 테이블에 있는 ROW를 찾아오는 것
  • 서로 독립적인 데이터들간의 조인을 이용해서 필요한 정보를 참조한다
  • 해당열에 존재하는 공통 값, 일반적으로 PK(기본키) 및 FK(외래키) 열을 조건으로 사용하여 한 테이블의 행을 다른 테이블의 행에 조인할 수 있다.
  • N개의 테이블을 조인하려면 최소 N-1개의 조인 조건이 필요하다
  • 조인 조건이 존재하지 않는다면 존재하는 모든 경우의 수를 조합하여 출력하기 때문에 데이터의 양이 비정상적으로 늘어난다
  • ANSI 방식의 JOIN과 ORACLE 방식의 JOIN 문법이 존재한다.

 

Q1 ) EMP테이블과 DEPT테이블을 합쳐서 출력하라

SQL> SELECT *
  2  FROM EMP,DEPT
  3  ORDER BY EMPNO;
   EMPNO ENAME                JOB                     MGR HIREDATE      SAL     COMM   DEPTNO   DEPTNO DNAME                        LOC
-------- -------------------- ------------------ -------- -------- -------- -------- -------- -------- ---------------------------- --------------------------
    7369 SMITH                CLERK                  7902 80/12/17      800                20       10 ACCOUNTING                   NEW YORK
    7369 SMITH                CLERK                  7902 80/12/17      800                20       30 SALES                        CHICAGO
    7369 SMITH                CLERK                  7902 80/12/17      800                20       20 RESEARCH                     DALLAS
    7369 SMITH                CLERK                  7902 80/12/17      800                20       40 OPERATIONS                   BOSTON
    7499 ALLEN                SALESMAN               7698 81/02/20     1600      300       30       30 SALES                        CHICAGO
    7499 ALLEN                SALESMAN               7698 81/02/20     1600      300       30       20 RESEARCH                     DALLAS
    7499 ALLEN                SALESMAN               7698 81/02/20     1600      300       30       10 ACCOUNTING                   NEW YORK
    7499 ALLEN                SALESMAN               7698 81/02/20     1600      300       30       40 OPERATIONS                   BOSTON
    .
    .
    .

조건이 설정되어 있지 않기 때문에 모든 조건에 대해서 결과값이 출력된다.

 

Q2) EMP 테이블과 DEPT 테이블의 DEPTNO가 같은 경우로 출력하라

SQL> SELECT * FROM EMP,DEPT
  2  WHERE EMP.DEPTNO = DEPT.DEPTNO
  3  ORDER BY EMPNO;
   EMPNO ENAME                JOB                     MGR HIREDATE      SAL     COMM   DEPTNO   DEPTNO DNAME                        LOC
-------- -------------------- ------------------ -------- -------- -------- -------- -------- -------- ---------------------------- --------------------------
    7369 SMITH                CLERK                  7902 80/12/17      800                20       20 RESEARCH                     DALLAS
    7499 ALLEN                SALESMAN               7698 81/02/20     1600      300       30       30 SALES                        CHICAGO
    7521 WARD                 SALESMAN               7698 81/02/22     1250      500       30       30 SALES                        CHICAGO
    7566 JONES                MANAGER                7839 81/04/02     2975                20       20 RESEARCH                     DALLAS
    7654 MARTIN               SALESMAN               7698 81/09/28     1250     1400       30       30 SALES                        CHICAGO
    7698 BLAKE                MANAGER                7839 81/05/01     2850                30       30 SALES                        CHICAGO
    7782 CLARK                MANAGER                7839 81/06/09     2450                10       10 ACCOUNTING                   NEW YORK
    7839 KING                 PRESIDENT                   81/11/17     5000                10       10 ACCOUNTING                   NEW YORK
    7844 TURNER               SALESMAN               7698 81/09/08     1500        0       30       30 SALES                        CHICAGO
    7900 JAMES                CLERK                  7698 81/12/03      950                30       30 SALES                        CHICAGO
    7902 FORD                 ANALYST                7566 81/12/03     3000                20       20 RESEARCH                     DALLAS
    7934 MILLER               CLERK                  7782 82/01/23     1300                10       10 ACCOUNTING                   NEW YORK

양 테이블의 DEPTNO가 같다는 조건을 붙였기 때문에 데이터의 양이 크게 정제되어 출력된 것을 확인할 수 있다.

 

 

1. INNER JOIN

  • 각 테이블의 특정 열에 일치한 데이터를 기준으로 조인을 하는 방식
  • 대부분 가장 많이 사용하는 조인 형식
  • 두 테이블에 대해 교집합의 요소를 가져온다
  • EQUI JOIN, SIMPLE JOIN이라고도 부른다

 

1) ANSI

  • USING 문을 사용하면 컬럼을 선택해서 조인할 수 있다.
  • ON은 다른 칼럼을 조회할 떄

Q1 ) INNER JOIN을 사용하여 TEST_EMP 테이블의 사원번호, 이름, 부서번호, 부서명을 조회하자

SQL> SELECT EMPNO, ENAME, DEPTNO, DNAME FROM TEST_EMP JOIN DEPT USING(DEPTNO);

   EMPNO ENAME                  DEPTNO DNAME
-------- -------------------- -------- ----------------------------
    7782 CLARK                      10 ACCOUNTING
    7934 MILLER                     10 ACCOUNTING
    7839 KING                       10 ACCOUNTING
    7566 JONES                      20 RESEARCH
    7369 SMITH                      20 RESEARCH
     333 333                        20 RESEARCH
     444 444                        20 RESEARCH
    7902 FORD                       20 RESEARCH
    7844 TURNER                     30 SALES
    7900 JAMES                      30 SALES
     222 222                        30 SALES
    7499 ALLEN                      30 SALES
     111 111                        30 SALES
    7521 WARD                       30 SALES
    7654 MARTIN                     30 SALES
    7698 BLAKE                      30 SALES

 

Q2 ) TEST_EMP 테이블에 부서배치 받지 않는 사원을 추가해서 INNER JOIN을 실행하자

SQL> INSERT INTO TEST_EMP(ENAME,DEPTNO) VALUES(777,NULL);

1 row created.

SQL> SELECT EMPNO, ENAME, DEPTNO, DNAME FROM TEST_EMP JOIN DEPT USING(DEPTNO);

   EMPNO ENAME                  DEPTNO DNAME
-------- -------------------- -------- ----------------------------
    7782 CLARK                      10 ACCOUNTING
    7934 MILLER                     10 ACCOUNTING
    7839 KING                       10 ACCOUNTING
     333 333                        20 RESEARCH
    7369 SMITH                      20 RESEARCH
    7902 FORD                       20 RESEARCH
     444 444                        20 RESEARCH
    7566 JONES                      20 RESEARCH
     222 222                        30 SALES
     111 111                        30 SALES
    7900 JAMES                      30 SALES
    7844 TURNER                     30 SALES
    7698 BLAKE                      30 SALES
    7654 MARTIN                     30 SALES
    7521 WARD                       30 SALES
    7499 ALLEN                      30 SALES

부서배치가 안되었기 때문에 조인문의 조건에 맞지않아 '777'이라는 사원은 출력되지 않았다.

 

 

2. ORACLE 방식

 

1) 주의할 점

SQL> SELECT EMPNO, ENAME, DEPTNO, DNAME, LOC
  2  FROM EMP E, DEPT D
  3  WHERE E.DEPTNO = D.DEPTNO;
SELECT EMPNO, ENAME, DEPTNO, DNAME, LOC
                     *
ERROR at line 1:
ORA-00918: column ambiguously defined

EMP 테이블과 DEPT 테이블의 공통된 데이터인 DEPTNO를 통해 조인하려했지만 실패했다

 

이유는 어느 테이블의 속해있는 DEPTNO인지 구분하지 못하기 때문이다.

 

Q1 ) INNER JOIN을 사용하여 EMP 테이블의 사원번호, 이름, 부서번호, 부서명을 조회하자

SQL> SELECT E.ENAME,E.EMPNO, D.DEPTNO, D.DNAME, D.LOC
  2  FROM EMP E, DEPT D
  3  WHERE E.DEPTNO = D.DEPTNO
  4  ORDER BY E.DEPTNO, D.DEPTNO;

ENAME                   EMPNO   DEPTNO DNAME                        LOC
-------------------- -------- -------- ---------------------------- --------------------------
CLARK                    7782       10 ACCOUNTING                   NEW YORK
KING                     7839       10 ACCOUNTING                   NEW YORK
MILLER                   7934       10 ACCOUNTING                   NEW YORK
SMITH                    7369       20 RESEARCH                     DALLAS
FORD                     7902       20 RESEARCH                     DALLAS
JONES                    7566       20 RESEARCH                     DALLAS
JAMES                    7900       30 SALES                        CHICAGO
TURNER                   7844       30 SALES                        CHICAGO
MARTIN                   7654       30 SALES                        CHICAGO
WARD                     7521       30 SALES                        CHICAGO
ALLEN                    7499       30 SALES                        CHICAGO
BLAKE                    7698       30 SALES                        CHICAGO

위와같이 어느 테이블의 어느 데이터인지 명시를 해줘야 정확히 출력이 되는것을 확인 할 수 있다.

 

 

# SALESMAN의 사원번호, 이름, 급여, 부서명, 근무지를 리턴한다

 

1) ANSI

SQL> SELECT EMPNO, ENAME, SAL, JOB, DNAME, LOC
  2  FROM EMP
  3  JOIN DEPT USING(DEPTNO)
  4  WHERE JOB = 'SALESMAN';

   EMPNO ENAME                     SAL JOB                LOC
-------- -------------------- -------- ------------------ --------------------------
    7499 ALLEN                    1600 SALESMAN           CHICAGO
    7844 TURNER                   1500 SALESMAN           CHICAGO
    7654 MARTIN                   1250 SALESMAN           CHICAGO
    7521 WARD                     1250 SALESMAN           CHICAGO

 

2. ORACLE

SQL> SELECT E.ENAME,E.EMPNO, D.DEPTNO, D.DNAME, D.LOC
  2  FROM EMP E, DEPT D
  3  WHERE E.JOB = 'SALESMAN' AND E.DEPTNO = D.DEPTNO;

ENAME                   EMPNO   DEPTNO DNAME                        LOC
-------------------- -------- -------- ---------------------------- --------------------------
ALLEN                    7499       30 SALES                        CHICAGO
TURNER                   7844       30 SALES                        CHICAGO
MARTIN                   7654       30 SALES                        CHICAGO
WARD                     7521       30 SALES                        CHICAGO

 

 

2. OUTER JOIN(외부조인)

  • 주종관계를 만들어서 주 테이블은 전체 출력, 종 테이블은 True값만 출력
  • 어느 열의 어느 한쪽이 NULL값이어도 강제로 출력하는 방식이 OUTER JOIN이다.

Q) EMP 테이블과 DEPT 테이블에서 EMP 테이블에 있는 모든 자료를 사원번호, 이름, 직업 DEPT 테이블의 부서번호, 부서명을 조회하자

 

1) ANSI

SQL> SELECT EMPNO,ENAME,JOB,DEPTNO,DNAME
  2  FROM EMP LEFT OUTER JOIN DEPT USING(DEPTNO);

   EMPNO ENAME                JOB                  DEPTNO DNAME
-------- -------------------- ------------------ -------- ----------------------------
    7934 MILLER               CLERK                    10 ACCOUNTING
    7839 KING                 PRESIDENT                10 ACCOUNTING
    7782 CLARK                MANAGER                  10 ACCOUNTING
    7902 FORD                 ANALYST                  20 RESEARCH
    7566 JONES                MANAGER                  20 RESEARCH
    7369 SMITH                CLERK                    20 RESEARCH
    7900 JAMES                CLERK                    30 SALES
    7844 TURNER               SALESMAN                 30 SALES
    7698 BLAKE                MANAGER                  30 SALES
    7654 MARTIN               SALESMAN                 30 SALES
    7521 WARD                 SALESMAN                 30 SALES
    7499 ALLEN                SALESMAN                 30 SALES
SQL> SELECT EMPNO,ENAME,JOB,DEPTNO,DNAME
  2  FROM EMP RIGHT OUTER JOIN DEPT USING(DEPTNO);

   EMPNO ENAME                JOB                  DEPTNO DNAME
-------- -------------------- ------------------ -------- ----------------------------
    7839 KING                 PRESIDENT                10 ACCOUNTING
    7782 CLARK                MANAGER                  10 ACCOUNTING
    7934 MILLER               CLERK                    10 ACCOUNTING
    7902 FORD                 ANALYST                  20 RESEARCH
    7369 SMITH                CLERK                    20 RESEARCH
    7566 JONES                MANAGER                  20 RESEARCH
    7900 JAMES                CLERK                    30 SALES
    7844 TURNER               SALESMAN                 30 SALES
    7654 MARTIN               SALESMAN                 30 SALES
    7521 WARD                 SALESMAN                 30 SALES
    7499 ALLEN                SALESMAN                 30 SALES
    7698 BLAKE                MANAGER                  30 SALES
                                                       40 OPERATIONS

 

 

2) ORACLE

SQL> SELECT E.EMPNO, E.ENAME, E.JOB, D.DEPTNO, D.DNAME
  2  FROM DEPT D, EMP E
  3  WHERE D.DEPTNO = E.DEPTNO(+);

   EMPNO ENAME                JOB                  DEPTNO DNAME
-------- -------------------- ------------------ -------- ----------------------------
    7839 KING                 PRESIDENT                10 ACCOUNTING
    7782 CLARK                MANAGER                  10 ACCOUNTING
    7934 MILLER               CLERK                    10 ACCOUNTING
    7902 FORD                 ANALYST                  20 RESEARCH
    7369 SMITH                CLERK                    20 RESEARCH
    7566 JONES                MANAGER                  20 RESEARCH
    7900 JAMES                CLERK                    30 SALES
    7844 TURNER               SALESMAN                 30 SALES
    7654 MARTIN               SALESMAN                 30 SALES
    7521 WARD                 SALESMAN                 30 SALES
    7499 ALLEN                SALESMAN                 30 SALES
    7698 BLAKE                MANAGER                  30 SALES
                                                       40 OPERATIONS

DEPT 테이블을 주 테이블, EMP 테이블을 종 테이블로 설정하고, 종 테이블의 조건에 (+)를 사용해야 한다.

 

이 OUTER JOIN을 LEFT OUTER JOIN이라고 부른다.

 

DEPT 테이블을 주 테이블로 구성했기에 DEPT 테이블의 DNAME 데이터가 전부 출력된 것을 확인할 수 있다.

 

SQL> SELECT E.EMPNO, E.ENAME, E.JOB, D.DEPTNO, D.DNAME
  2  FROM DEPT D, EMP E
  3  WHERE D.DEPTNO(+) = E.DEPTNO;

   EMPNO ENAME                JOB                  DEPTNO DNAME
-------- -------------------- ------------------ -------- ----------------------------
    7934 MILLER               CLERK                    10 ACCOUNTING
    7839 KING                 PRESIDENT                10 ACCOUNTING
    7782 CLARK                MANAGER                  10 ACCOUNTING
    7902 FORD                 ANALYST                  20 RESEARCH
    7566 JONES                MANAGER                  20 RESEARCH
    7369 SMITH                CLERK                    20 RESEARCH
    7900 JAMES                CLERK                    30 SALES
    7844 TURNER               SALESMAN                 30 SALES
    7698 BLAKE                MANAGER                  30 SALES
    7654 MARTIN               SALESMAN                 30 SALES
    7521 WARD                 SALESMAN                 30 SALES
    7499 ALLEN                SALESMAN                 30 SALES

이 OUTER JOIN은 RIGHT OUTER JOIN 이다.

 

DEPT 테이블이 종 테이블이기 떄문에 40번에 대한 내용이 생략된 것을 알 수 있다.

 

 

EX) 테이블을 간단하게 만들어서 확인해보자

SQL> SELECT * FROM X;	
S1   X2
---- ----
YA
YB   1
C

SQL> SELECT * FROM Y;
S1   Y2
---- ----
YA
YB   1
SQL> SELECT * FROM X LEFT OUTER JOIN Y USING(S1);

S1   X2   Y2
---- ---- ----
YA
YB   1    1
C

SQL> SELECT * FROM X RIGHT OUTER JOIN Y USING(S1);

S1   X2   Y2
---- ---- ----
YA
YB   1    1

# LEFT JOIN의 경우 X 테이블 내용 전체 출력, RIGHT JOIN의 경우 Y테이블 S1전체내용 출력

즉 주테이블의 내용은 전체 출력, 종 테이블의 출력은 맞는 것만 출력한다.

 

 

3. SELF JOIN

  • 동일 테이블에서의 조인을 말한다.

Q ) ##사원의 관리자는 ##이다.

 

 

1) ANSI

SQL> SELECT E.ENAME ||'사원의 관리자는'|| M.ENAME ||'이다' AS "관리자 정보"
  2  FROM EMP E LEFT OUTER JOIN EMP M ON(E.MGR = M.EMPNO);

관리자 정보
------------------------------------------------------------------------------------------------
FORD사원의 관리자는JONES이다
JAMES사원의 관리자는BLAKE이다
TURNER사원의 관리자는BLAKE이다
MARTIN사원의 관리자는BLAKE이다
WARD사원의 관리자는BLAKE이다
ALLEN사원의 관리자는BLAKE이다
MILLER사원의 관리자는CLARK이다
CLARK사원의 관리자는KING이다
BLAKE사원의 관리자는KING이다
JONES사원의 관리자는KING이다
SMITH사원의 관리자는FORD이다
KING사원의 관리자는이다

 

2) ORACLE

SQL> SELECT E.ENAME ||'사원의 관리자는'|| M.ENAME ||'이다' AS "관리자 정보"
  2  FROM EMP E, EMP M
  3  WHERE E.MGR = M.EMPNO(+);

관리자 정보
------------------------------------------------------------------------------------------------
FORD사원의 관리자는JONES이다
JAMES사원의 관리자는BLAKE이다
TURNER사원의 관리자는BLAKE이다
MARTIN사원의 관리자는BLAKE이다
WARD사원의 관리자는BLAKE이다
ALLEN사원의 관리자는BLAKE이다
MILLER사원의 관리자는CLARK이다
CLARK사원의 관리자는KING이다
BLAKE사원의 관리자는KING이다
JONES사원의 관리자는KING이다
SMITH사원의 관리자는FORD이다
KING사원의 관리자는이다

 

 

4. NATURAL JOIN

  • 조인 대상이 되는 두 테이블에 이름과 자료형이 같은 열을 찾은 후 그 열을 기준으로 등가조인을 해주는 방식
SQL> SELECT E.ENAME, DEPTNO, D.DNAME FROM EMP E NATURAL JOIN DEPT D;

ENAME                  DEPTNO DNAME
-------------------- -------- ----------------------------
KING                       10 ACCOUNTING
CLARK                      10 ACCOUNTING
MILLER                     10 ACCOUNTING
FORD                       20 RESEARCH
SMITH                      20 RESEARCH
JONES                      20 RESEARCH
JAMES                      30 SALES
TURNER                     30 SALES
MARTIN                     30 SALES
WARD                       30 SALES
ALLEN                      30 SALES
BLAKE                      30 SALES

공통 열 DEPTNO를 가지고 있는 두 테이블에 대해 NATURL JOIN은 DEPTNO 열을 기준으로 등가 조인을 시켜준다.

 

 

5. CROSS JOIN

  • 한 쪽 테이블의 모든 행과 다른 테이블의 모든 행을 JOIN시킨다.
  • 즉 이 조인의 결과는 각 행을 곱한것과 같다.
SQL> SELECT E.ENAME, D.DNAME FROM EMP E CROSS JOIN DEPT D;

ENAME                DNAME
-------------------- ----------------------------
SMITH                ACCOUNTING
ALLEN                ACCOUNTING
WARD                 ACCOUNTING
JONES                ACCOUNTING
MARTIN               ACCOUNTING
BLAKE                ACCOUNTING
CLARK                ACCOUNTING
KING                 ACCOUNTING
TURNER               ACCOUNTING
JAMES                ACCOUNTING
FORD                 ACCOUNTING
...
48 rows selected.

ENAME = 12, DNAME = 4 -> 48

 

 

6. NON-EQUI JOIN

  • 이름 그대로 등가 조인 방식 외의 방식을 뜻한다.

# SAL 등급을 보여주는 SALGRADE 테이블

SQL> SELECT * FROM SALGRADE;

   GRADE    LOSAL    HISAL
-------- -------- --------
       1      700     1200
       2     1201     1400
       3     1401     2000
       4     2001     3000
       5     3001     9999

 

Q) 급여 범위를 확인해보자.

 

1) ANSI

SQL> SELECT ENAME,SAL,GRADE FROM EMP JOIN SALGRADE ON(SAL BETWEEN LOSAL AND HISAL);

ENAME                     SAL    GRADE
-------------------- -------- --------
SMITH                     800        1
JAMES                     950        1
WARD                     1250        2
MARTIN                   1250        2
MILLER                   1300        2
TURNER                   1500        3
ALLEN                    1600        3
CLARK                    2450        4
BLAKE                    2850        4
JONES                    2975        4
FORD                     3000        4
KING                     5000        5

 

 

2) ORACLE

SQL> SELECT EMPNO,ENAME,JOB,SAL,GRADE
  2  FROM SALGRADE, EMP
  3  WHERE SAL BETWEEN LOSAL AND HISAL;

   EMPNO ENAME                JOB                     SAL    GRADE
-------- -------------------- ------------------ -------- --------
    7369 SMITH                CLERK                   800        1
    7900 JAMES                CLERK                   950        1
    7521 WARD                 SALESMAN               1250        2
    7654 MARTIN               SALESMAN               1250        2
    7934 MILLER               CLERK                  1300        2
    7844 TURNER               SALESMAN               1500        3
    7499 ALLEN                SALESMAN               1600        3
    7782 CLARK                MANAGER                2450        4
    7698 BLAKE                MANAGER                2850        4
    7566 JONES                MANAGER                2975        4
    7902 FORD                 ANALYST                3000        4
    7839 KING                 PRESIDENT              5000        5

급여 등급은 급여가 일치하는 것이 아닌, 최소급여와 최대급여 사이에 값이 있어야 하기 때문에 열의 일치여부로 테이블을 조인하는 등가조인 방식은 사용할 수 없다. 따라서 BETWEEN A AND B를 이용하여 범위를 지정해줘야한다.

 

# WHERE 조건절이 없다면 ENAME = 14, SAL = 5 -> 70개의 결과가 출력된다.

'IT > DataBase' 카테고리의 다른 글

SQL - SUBQUERY  (0) 2021.05.25
SQL - SET  (0) 2021.05.25
SQL - 그룹함수  (0) 2021.05.21
SQL - 날짜/문자  (0) 2021.05.18
SQL - DML(SELECT)  (0) 2021.05.17