DATABASE

[오라클] JOIN(조인) / UNION / UNION ALL / INTERSECT / MINUS

온풀 2022. 3. 12. 00:56
20220225_01_scott.sql / 오라클 9일 차

JOIN(조인)

-- 1. SQL 1992 CODE

-- CROSS JOIN
SELECT *
FROM EMP;

SELECT *
FROM DEPT;

SELECT *
FROM EMP, DEPT;
--> 수학에서 말하는 데카르트 곱(CARTESIAN PRODUCT)
--  두 테이블을 결합한 모든 경우의 수

-- EQUI JOIN : 서로 정확히 일치하는 것들끼리 연결하여 결합시키는 결합 방법
SELECT *
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;

SELECT *
FROM EMP E, DEPT D -- 별칭 부여
WHERE E.DEPTNO = D.DEPTNO;


-- NON EQUI JOIN : 범위 안에 적합한 것들끼리 연결하여 결합시키는 결합 방법
SELECT *
FROM EMP;

SELECT *
FROM SALGRADE;

SELECT *
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;


-- EQUI JOIN 시 (+) 를 활용한 결합 방법

SELECT *
FROM TBL_EMP;
--> 19명의 사원 중 부서번호를 갖지 못한 사원들은 5

SELECT *
FROM TBL_DEPT;
--> 5개의 부서 중 소속사원을 갖지 못한 부서는 2

SELECT *
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO = D.DEPTNO;
--> 총 14건의 데이터가 결합되어 조회된 상황
--  즉, 부서번호를 갖지 못한 사원들(5) 모두 누락
--  또한, 소속 사원을 갖지 못한 부서(2) 모두 누락


SELECT *
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO = D.DEPTNO(+); -- 덧셈 연산자가 붙어 있지 않는 쪽을 먼저 구성 후, 맞는 애들을 부가하는 거
--> 총 19건의 데이터가 결합되어 조회된 상황

SELECT *
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO;
--> 총 16건의 데이터가 결합되어 조회된 상황


--※ (+) 가 없는 쪽 테이블의 데이터를 모두 메모리에 먼저 적재한 후
--   (+) 가 있는 쪽 테이블의 데이터를 하나하나 확인하여 결합시키는 형태로
--   JOIN이 이루어지게 된다.

--   이와 같은 이유로...
SELECT *
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO(+);
-- 이런 형식의 JOIN은 존재하지 않는다.
--==>> 에러 발생
--     (ORA-01468: a predicate may reference only one outer-joined table)


-- 2. SQL 1999 CODE -- 99년에 표준화됨 / 92코드도 기억해놔야 함, 많이 쓰임
--                  → 『JOIN』 키워드 등장 → 『JOIN』 (결합)의 유형 명시
--                  → 『ON』 키워드 등장 → 결합 조건은 WHERE 대신 ON

-- CROSS JOIN
SELECT *
FROM EMP CROSS JOIN DEPT;

-- INNER JOIN
/*
SELECT *
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO; --1992 코드
*/

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

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

SELECT *
FROM EMP E JOIN DEPT D
ON E.DEPTNO = D.DEPTNO;
-- INNER JOIN 에서 INNER 는 생략 가능

-- OUTER JOIN -- 92코드에서 덧셈 기호 붙였던 게 아우터 조인으로 바뀜
/*
SELECT *
FROM TBL_EMP, TBL_DEPT
WHERE TBL_EMP.DEPTNO = TBL_DEPT.DEPTNO(+); -- 1992 코드
*/

SELECT *
FROM TBL_EMP E LEFT OUTER JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO;

SELECT *
FROM TBL_EMP E RIGHT OUTER JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO;

SELECT *
FROM TBL_EMP E FULL OUTER JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO;

-- 모두 'OUTER' 생략 가능하다!
-- 그럼 어떻게 구분하냐?
-- 방향이 적혀 있으면 OUTER 조인!!

SELECT *
FROM TBL_EMP E LEFT JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO;

SELECT *
FROM TBL_EMP E RIGHT JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO;

SELECT *
FROM TBL_EMP E FULL JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO;

--------------------------------------------------------------------------------

SELECT *
FROM TBL_EMP E JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO
AND JOB = 'CLERK'; -- 이 구문 자체도 결합조건으로 처리되는 거니까, 적절하지는 않다!
--> 이와 같은 방법으로 쿼리문을 구성해도
--  조회 결과를 얻는 과정에 문제는 없다.
--  그러나 이렇게 하지 말자

-- 이렇게 하자
SELECT *
FROM TBL_EMP E JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO
WHERE JOB = 'CLERK';
-- 이와 같이 구성하여
-- 조회하는 것을 권장한다.

--------------------------------------------------------------------------------

--○ EMP 테이블과 DEPT 테이블을 대상으로
--   직종이 MANAGER 와 CLERK 인 사원들만 조회한다.
--   부서번호, 부서명, 사원명, 직종명, 급여 항목을 조회한다.

-- 수업 풀이 ------------------------------------------------------------------- 

--○ EMP 테이블과 DEPT 테이블을 대상으로
--   직종이 MANAGER 와 CLERK 인 사원들만 조회한다.
--   부서번호, 부서명, 사원명, 직종명, 급여 항목을 조회한다.
--   E, D      D       E       E       E

-- 각각의 테이블을 조회하는 것이 먼저다.
SELECT *
FROM EMP; 

SELECT *
FROM DEPT;

-- 먼저 92 코드로 써봅시다~
SELECT DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;
--==>> 에러 발생
--     (ORA-00918: column ambiguously defined)
--     DEPTNO 때문에 발생하는 것.

-- ↓DEPTNO 빼면 에러 안 남
SELECT DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;
-- DEPTNO가 양쪽에 있는데 나 어떻게 해요~ 이래서 에러나는 거

-- 두 테이블 간 중복되는 컬럼(DEPTNO)에 대한
-- 소속 테이블을 정해줘야(명시해줘야) 한다.

SELECT E.DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;
--==>>
/*
10    ACCOUNTING    CLARK    MANAGER        2450
10    ACCOUNTING    KING    PRESIDENT    5000
10    ACCOUNTING    MILLER    CLERK        1300
20    RESEARCH    JONES    MANAGER        2975
20    RESEARCH    FORD    ANALYST        3000
20    RESEARCH    ADAMS    CLERK        1100
20    RESEARCH    SMITH    CLERK         800
20    RESEARCH    SCOTT    ANALYST        3000
30    SALES        WARD    SALESMAN    1250
30    SALES        TURNER    SALESMAN    1500
30    SALES        ALLEN    SALESMAN    1600
30    SALES        JAMES    CLERK         950
30    SALES        BLAKE    MANAGER        2850
30    SALES        MARTIN    SALESMAN    1250
*/

SELECT D.DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;
--==>>
/*
10    ACCOUNTING    CLARK    MANAGER        2450
10    ACCOUNTING    KING    PRESIDENT    5000
10    ACCOUNTING    MILLER    CLERK        1300
20    RESEARCH    JONES    MANAGER        2975
20    RESEARCH    FORD    ANALYST        3000
20    RESEARCH    ADAMS    CLERK        1100
20    RESEARCH    SMITH    CLERK         800
20    RESEARCH    SCOTT    ANALYST        3000
30    SALES        WARD    SALESMAN    1250
30    SALES        TURNER    SALESMAN    1500
30    SALES        ALLEN    SALESMAN    1600
30    SALES        JAMES    CLERK         950
30    SALES        BLAKE    MANAGER        2850
30    SALES        MARTIN    SALESMAN    1250
*/

SELECT D.DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;
-- E.DEPTNO, E.DEPTNO 둘 다 써도 될까요? -- ㄴㄴ 안 돼요~

--※ 두 테이블 간 중복되는 컬럼에 대해 소속 테이블을 명시하는 경우
--   부모 테이블의 컬럼을 참조할 수 있도록 처리해야 한다.

-- 자바에서는 상속이라는 문법이 존재했으나 오라클에는 없다. 그럼 어떻게 구분하느냐.

/*
오라클은 관계형 데이터베이스 관리 시스템
          R      DB           M    S
         ------
         중요한 개념

-- 자바에서 여러개의 작은 클래스가 더 힘이 세다.
-- 마찬가지로 오라클에서도 여러 개로 쪼개져있는 테이블을 만드는 게 핵심구조이다.
-- 오라클 하고 나면 JDBC라는 작업을 수행하게 될 때도, 웹 클라이언트에서도, 서버에서도 모두 나누는 게 핵심이 될 것.
-- 모든 과목의 핵심 키워드는 --> 분리!!!

-- 여러 개로 나누어진 각기 다른 테이블들끼리 연관성이 있어야 관계가 있는 것 
-- 두 테이블이 관계를 맺고 있어야 부모 자식이 확인이 된다.

-- 부모 자식을 확인할 수 있는 가장 좋은 방법 --> 연결고리 확인!!!
-- 연결 고리 컬럼 -> DEPTNO !
*/

SELECT *
FROM EMP; --> DEPTNO 여러 개 / 자식 테이블

SELECT *
FROM DEPT; --> DEPTNO 각 한 개씩!!! / 부모 테이블

--> DEPT의 DEPTNO 컬럼을 EMP에서 여럿이 참조하는 상황
--  한 부모의 여러 자식 가능 --> DEPT가 부모테이블이다~!

-- 최종 풀이
SELECT D.DEPTNO, DNAME, E.ENAME, E.JOB, E.SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
  AND E.JOB IN ('MANAGER', 'CLERK');
--==>>
/*
10    ACCOUNTING    CLARK    MANAGER    2450
10    ACCOUNTING    MILLER    CLERK    1300
20    RESEARCH    ADAMS    CLERK    1100
20    RESEARCH    JONES    MANAGER    2975
20    RESEARCH    SMITH    CLERK     800
30    SALES        BLAKE    MANAGER    2850
30    SALES        JAMES    CLERK     950
*/

--------------------------------------------------------------------------------
-- 왜 부모 테이블을 참조해야 하는지 설명

SELECT E.DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO;
--==>>
/*
10        ACCOUNTING    CLARK    MANAGER        2450
10        ACCOUNTING    KING    PRESIDENT    5000
10        ACCOUNTING    MILLER    CLERK        1300
20        RESEARCH    JONES    MANAGER        2975
20        RESEARCH    FORD    ANALYST        3000
20        RESEARCH    ADAMS    CLERK        1100
20        RESEARCH    SMITH    CLERK         800
20        RESEARCH    SCOTT    ANALYST     3000
30        SALES        WARD    SALESMAN    1250
30        SALES        TURNER    SALESMAN    1500
30        SALES        ALLEN    SALESMAN    1600
30        SALES        JAMES    CLERK         950
30        SALES        BLAKE    MANAGER        2850
30        SALES        MARTIN    SALESMAN    1250
(null)    OPERATIONS    (null)    (null)       (null) --> DEPTNO 없음 (자식테이블 참조)
*/

SELECT D.DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO;
--==>>
/*
10    ACCOUNTING    CLARK    MANAGER        2450
10    ACCOUNTING    KING    PRESIDENT    5000
10    ACCOUNTING    MILLER    CLERK        1300
20    RESEARCH    JONES    MANAGER        2975
20    RESEARCH    FORD    ANALYST        3000
20    RESEARCH    ADAMS    CLERK        1100
20    RESEARCH    SMITH    CLERK         800
20    RESEARCH    SCOTT    ANALYST        3000
30    SALES        WARD    SALESMAN    1250
30    SALES        TURNER    SALESMAN    1500
30    SALES        ALLEN    SALESMAN    1600
30    SALES        JAMES    CLERK         950
30    SALES        BLAKE    MANAGER        2850
30    SALES        MARTIN    SALESMAN    1250
40    OPERATIONS    (null)    (null)       (null) --> DEPTNO 있음 (부모테이블 참조)    
*/

SELECT D.DEPTNO, D.DNAME, E.ENAME, E.JOB, E.SAL --> 얘네들도 소속 테이블 표시를 하도록 당부합니다!
FROM EMP E, DEPT D                                
WHERE E.DEPTNO = D.DEPTNO;
--> 이유
--  위에서 DEPTNO의 소속을 표시하지 않았을 때 에러가 났다는 것은, 
--  SELECT 문에서 D와 E를 모두 다녀온다는 것
--  다른 컬럼들도 명시해 주면 오라클이 빠르게 일할 수 있도록 도와줄 수 있다.
--  쌤의 개인적인 권장!!

--※ 두 테이블에 모두 포함되어 있는 중복된 컬럼이 아니더라도
--   조인하는 과정에서 컬럼의 소속 테이블을 명시해 줄 수 있도록 권장한다.

--------------------------------------------------------------------------------
--○ SELF JOIN (자기 조인)

-- EMP 테이블의 데이터를 다음과 같이 조회할 수 있도록
-- 쿼리문을 구성한다.
-----------------------------------------------------------
-- 사원번호 사원명 직종명 관리자번호 관리자명 관리자직종명
-----------------------------------------------------------
-- 7369     SMITH  CLERK  7902       FORD     ANALYST

-- 수업 풀이 -------------------------------------------------------------------

-- EMP 테이블의 데이터를 다음과 같이 조회할 수 있도록
-- 쿼리문을 구성한다.
-----------------------------------------------------------
-- 사원번호 사원명 직종명 관리자번호 관리자명 관리자직종명
-----------------------------------------------------------
-- 7369     SMITH  CLERK  7902       FORD     ANALYST
--  |         |      |     |          |         |
-- EMP1     EMP1   EMP1   EMP1        |         |
--                        (MGR)       |         |
--                         |          |         |
--                        EMP2      EMP2      EMP2
--                       (EMPNO)

SELECT E1.EMPNO "사원번호", E1.ENAME "사원명", E1.JOB "직종명", E2.EMPNO "관리자번호" --E1.MGR"관리자번호"
     , E2.ENAME "관리자명", E2.JOB "관리자직종명"
FROM EMP E1 LEFT JOIN EMP E2 -- 그냥 JOIN 하면 KING이 누락됨 -- 관리자가 NULL
ON E1.MGR = E2.EMPNO; 
--==>>
/*
7902    FORD    ANALYST        7566    JONES    MANAGER
7788    SCOTT    ANALYST        7566    JONES    MANAGER
7900    JAMES    CLERK        7698    BLAKE    MANAGER
7844    TURNER    SALESMAN    7698    BLAKE    MANAGER
7654    MARTIN    SALESMAN    7698    BLAKE    MANAGER
7521    WARD    SALESMAN    7698    BLAKE    MANAGER
7499    ALLEN    SALESMAN    7698    BLAKE    MANAGER
7934    MILLER    CLERK        7782    CLARK    MANAGER
7876    ADAMS    CLERK        7788    SCOTT    ANALYST
7782    CLARK    MANAGER     7839    KING    PRESIDENT
7698    BLAKE    MANAGER        7839    KING    PRESIDENT
7566    JONES    MANAGER        7839    KING    PRESIDENT
7369    SMITH    CLERK        7902    FORD    ANALYST
7839    KING    PRESIDENT    (null)    (null)    (null)
*/

-- 92코드
SELECT E1.EMPNO "사원번호", E1.ENAME "사원명", E1.JOB "직종명", E2.EMPNO "관리자번호" 
     , E2.ENAME "관리자명", E2.JOB "관리자직종명"
FROM EMP E1, EMP E2 
WHERE E1.MGR = E2.EMPNO(+); 
--==>>
/*
7902    FORD    ANALYST        7566    JONES    MANAGER
7788    SCOTT    ANALYST        7566    JONES    MANAGER
7900    JAMES    CLERK        7698    BLAKE    MANAGER
7844    TURNER    SALESMAN    7698    BLAKE    MANAGER
7654    MARTIN    SALESMAN    7698    BLAKE    MANAGER
7521    WARD    SALESMAN    7698    BLAKE    MANAGER
7499    ALLEN    SALESMAN    7698    BLAKE    MANAGER
7934    MILLER    CLERK        7782    CLARK    MANAGER
7876    ADAMS    CLERK        7788    SCOTT    ANALYST
7782    CLARK    MANAGER     7839    KING    PRESIDENT
7698    BLAKE    MANAGER        7839    KING    PRESIDENT
7566    JONES    MANAGER        7839    KING    PRESIDENT
7369    SMITH    CLERK        7902    FORD    ANALYST
7839    KING    PRESIDENT    (null)    (null)    (null)
*/

세 개 이상의 테이블 조인(JOIN)

-- 형식 1. (SQL 1992 CODE)
SELECT 테이블명1.컬럼명, 테이블명2.컬럼명, 테이블명3.컬럼명
FROM 테이블명1, 테이블명2, 테이블명3
WHERE 테이블명1.컬럼명1 = 테이블명2.컬럼명1
  AND 테이블명2.컬럼명2 = 테이블명3.컬럼명2;


-- 형식 2. (SQL 1999 CODE)
SELECT 테이블명1. 컬럼명, 테이블명2.컬럼명, 테이블명3.컬럼명
FROM 테이블명1 JOIN 테이블명2
ON 테이블명1.컬럼명1 = 테이블명2.컬럼명2
               JOIN 테이블명3
               ON 테이블명2.컬럼명2 = 테이블명3.컬럼명2;


--○ HR 계정 소유의 테이블 또는 뷰 목록 조회
SELECT *
FROM TAB;
--==>>
/*
COUNTRIES            TABLE    
DEPARTMENTS            TABLE    
EMPLOYEES            TABLE    
EMP_DETAILS_VIEW    VIEW    --    얘는 신경 안 써두 됨
JOBS                TABLE    
JOB_HISTORY            TABLE    
LOCATIONS            TABLE    
REGIONS                TABLE    
*/

--------------------------------------------------------------------------------

--○ HR.JOBS, HR.EMPLOYEES, HR.DEPARTMENTS 테이블을 대상으로 직원들의 데이터를  -- 문제
--   FIRST_NAME, LAST_NAME, JOB_TITLE, DEPARTMENT_NAME 항목으로 조회한다.
--   EMPLOYEES   EMPLOYEES  JOBS       DEPARTMENTS

-- 수업 풀이 -------------------------------------------------------------------

--○ HR.JOBS, HR.EMPLOYEES, HR.DEPARTMENTS 테이블을 대상으로 직원들의 데이터를  
--   FIRST_NAME, LAST_NAME, JOB_TITLE, DEPARTMENT_NAME 항목으로 조회한다.
--   ----------  ---------  ---------  ---------------
--   EMPLOYEES   EMPLOYEES  JOBS       DEPARTMENTS

SELECT *
FROM DEPARTMENTS;
-- DEPARTMENT_ID        -- 관계 컬럼

SELECT *
FROM EMPLOYEES; 
-- JOB_ID               -- 관계 컬럼

SELECT *
FROM JOBS; 

SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

SELECT COUNT(*)
FROM EMPLOYEES E JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
--==>> 106

SELECT COUNT(*)
FROM EMPLOYEES;
--==>> 107
-- OUTER 조인 해야 한다.

SELECT COUNT(*)
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
--==>> 107

SELECT E.FIRST_NAME, E.LAST_NAME, JOB_TITLE, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
          ON E.JOB_ID = J.JOB_ID;

SELECT COUNT(*)
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
          ON E.JOB_ID = J.JOB_ID;
--==>> 107

SELECT E.FIRST_NAME, E.LAST_NAME, JOB_TITLE, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
          ON E.JOB_ID = J.JOB_ID;


-- ※ JOIN 추가 → NATURAL JOIN --> 적극적으로 쓰는 건 권장 안 함
SELECT D.DEPTNO, D.DNAME, E.ENAME, E.SAL
FROM EMP E JOIN DEPT D
ON E.DEPTNO = D.DEPTNO;
--==>>
/*
10    ACCOUNTING    CLARK    2450
10    ACCOUNTING    KING    5000
10    ACCOUNTING    MILLER    1300
20    RESEARCH    JONES    2975
20    RESEARCH    FORD    3000
20    RESEARCH    ADAMS    1100
20    RESEARCH    SMITH     800
20    RESEARCH    SCOTT    3000
30    SALES        WARD    1250
30    SALES        TURNER    1500
30    SALES        ALLEN    1600
30    SALES        JAMES     950
30    SALES        BLAKE    2850
30    SALES        MARTIN    1250
*/

SELECT DEPTNO, DNAME, ENAME, SAL
FROM EMP JOIN DEPT;
--==>> 에러 발생
--     (ORA-00905: missing keyword)

SELECT DEPTNO, DNAME, ENAME, SAL
FROM EMP NATURAL JOIN DEPT;
--==>>
/*
10    ACCOUNTING    CLARK    2450
10    ACCOUNTING    KING    5000
10    ACCOUNTING    MILLER    1300
20    RESEARCH    JONES    2975
20    RESEARCH    FORD    3000
20    RESEARCH    ADAMS    1100
20    RESEARCH    SMITH    800
20    RESEARCH    SCOTT    3000
30    SALES        WARD    1250
30    SALES        TURNER    1500
30    SALES        ALLEN    1600
30    SALES        JAMES    950
30    SALES        BLAKE    2850
30    SALES        MARTIN    1250
*/

UNION / UNION ALL

--※ 컬럼과 컬럼의 관계를 고려하여 테이블을 결합하고자 하는 경우
--   JOIN을 사용하지만
--   레코드와 레크도를 결합하고자 하는 경우
--   UNION / UNION ALL 을 사용할 수 있다.

SELECT *
FROM TBL_JUMUNBACKUP;
SELECT *
FROM TBL_JUMUN;


SELECT *
FROM TBL_JUMUNBACKUP
UNION
SELECT *
FROM TBL_JUMUN;


SELECT *
FROM TBL_JUMUNBACKUP
UNION 
SELECT *
FROM TBL_JUMUN;


SELECT *
FROM TBL_JUMUNBACKUP
UNION ALL
SELECT *
FROM TBL_JUMUN;


SELECT *
FROM TBL_JUMUN
UNION ALL
SELECT *
FROM TBL_JUMUNBACKUP;

--※ UNION은 항상 결과물의 첫 번째 컬럼을 기준으로
--   오름차순 정렬을 수행한다.
--   UNION ALL 은 결합된 순서대로(테이블을 쿼리문에서 명시한 순서대로)
--   조회한 결과를 반환한다.(즉, 정렬 기능 없음)
--   이로 인해 UNION이 부하가 더 크다. (리소스 소모가 더 크다.)
--   또한, UNION은 결과물에 중복된 행이 존재할 경우
--   중복을 제거하고 1개 행만 조회된 결과를 반환하게 된다.

-- UNION보다 UNION ALL을 보통 더 많이 쓴다!!!

--○ 지금까지 주문받은 데이터들 통해
--   제품별 총 주문량을 조회할 수 있는 쿼리문을 구성한다.
SELECT T.JECODE, SUM(T.JUSU)
FROM
(
    SELECT JECODE, JUSU
    FROM TBL_JUMUN
    UNION ALL
    SELECT JECODE, JUSU
    FROM TBL_JUMUNBACKUP
) T
GROUP BY T.JECODE;
--==>>
/*
나아쵸    40
꼬북칩    30
맛동산    50
웨하스    50
눈감자    10
에이스    20
오감자    50
포카칩    60
거언빵    10
모옹쉘    30
빼빼로    190
홈런볼    410
고래밥    170
*/

INTERSECT / MINUS (→ 교집합과 차집합)

-- TBL_JUMUNBACKUP 테이블과 TBL_JUMUN 테이블에서
-- 제품코드와 주문수량의 값이 똑같은 행만 추출하고자 한다.
SELECT JECODE, JUSU
FROM TBL_JUMUNBACKUP
INTERSECT
SELECT JECODE, JUSU
FROM TBL_JUMUN;
--==>>
/*
모옹쉘    30
빼빼로    20
*/.