JOIN(19921999、CROSS、EQUI、INNER、OUTER、SELF、NATURAL)、データ復旧(不完全復旧)


結合は、2つのテーブルを組み合わせて結果を生成します.
VERSION① 1992 CODE
CROSS JOIN 크로스조인

SELECT *
FROM EMP, DEPT;
--> 수학에서 말하는 데카르트 곱(CARTESIAN PRODUCT)
-- 두 테이블을 결합한 『모든 경우의 수』
-- EQUI JOIN : 서로 정확히 일치하는 것들끼리 연결하여 결합시키는 결합 방법
SELECT *
FROM EMP,DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;
-- EQUI JOIN 이퀴 조인이 조인 안에서 가장 많이 쓰인다.


SELECT *
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;
-- 이렇게 테이블 별칭을 설정해서 EQUI JOIN을 쓸 수 있다.
-- NON EQUI JOIN : 범위 안에 적합한 것들끼리 연결하여 결합시키는 결합방법.

SELECT *
FROM EMP;

SELECT *
FROM SALGRADE;

SELECT *
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;
-- EMP 테이블의 SAL이 SALGRADE 안에 LOSAL과 HISAL 사이에 있는 값이면 그것끼리 결합
-- EQUI JOIN 시 (+) 를 활용한 결합 방법

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

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

SELECT * 
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO = D.DEPTNO;
--> 부서번호가 null이 아니면서, 부서번호가 40,50이 아닌애들끼리 결합
--> 부서번호를 갖지 못한 사원들 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은 존재하지 않는다.(양쪽 모두 첨가만 하겠다)
VERSION② 1999 CODE
1999年よりコードに『JOIN』キーワードが登場し、JOINのタイプを示す
『ON』キーワード登場→条件に合わせて『ON』でWHERE代わり
-- 1999 코드의 CROSS JOIN
SELECT *
FROM EMP CROSS JOIN DEPT; 

-- , 대신 JOIN이 들어갔다
-- 1992코드에서 ,로 CROSS JOIN 했던것과 같은 결과 반환
-- INNER JOIN
SELECT *
FROM EMP INNER JOIN DEPT   -- 1992 코드에서 ,로 EQUI JOIN 했던것과 같은 결과 반환
ON EMP.DEPTNO = DEPT.DEPTNO;  -- 결합조건이 WHERE가 아니라 『ON』 키워드

SELECT *
FROM EMP E INNER JOIN DEPT D -- 테이블에 별칭붙이는거 가능
ON E.DEPTNO = D.DEPTNO;

SELECT *
FROM EMP E JOIN DEPT D  -- INNER JOIN에서 INNER를 생략하는것 가능
ON E.DEPTNO = D.DEPTNO;
-- OUTER JOIN   
-- 1992 코드에서 (+)을 붙여 사용하는 EQUI JOIN이 OUTER JOIN으로 바뀜
SELECT *
FROM TBL_EMP E LEFT OUTER JOIN TBL_DEPT D  -- LEFT가 주인공
ON E.DEPTNO = D.DEPTNO;

SELECT *
FROM TBL_EMP E RIGHT OUTER JOIN TBL_DEPT D -- RIGTH가 주인공
ON E.DEPTNO = D.DEPTNO;

SELECT *
FROM TBL_EMP E FULL OUTER JOIN TBL_DEPT D  -- LEFT RIGHT 모두 나타냄.
ON E.DEPTNO = D.DEPTNO;
-- 1992코드에서는 양쪽 모두 (+)를 하면 오류가 났는데
1999 코드에서는 FULL OUTER JOIN이 새로생겼음

SELECT *
FROM TBL_EMP E LEFT JOIN TBL_DEPT D     -- LEFT OUTER JOIN에서 OUTER 생략가능
ON E.DEPTNO = D.DEPTNO;

SELECT *
FROM TBL_EMP E RIGHT JOIN TBL_DEPT D   -- RIGHT OUTER JOIN에서 OUTER 생략가능
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';
--> 하지만, AND가 아니라 WHERE을 사용해서 조회하는 것을 권장한다.
--> 왜냐면 ON은 결합조건, WHERE은 선택조건 이렇게 나눠서 구분하는게 좋기때문이다.
実習
--※ EMP 테이블과 DEPT 테이블을 대상으로
-- 직종이 MANAGER와 CLERK인 사원들만 조회한다.
-- 부서번호, 부서명, 사원명, 직종명, 급여항목을 조회한다.
SELECT *
FROM EMP;

SELECT *
FROM DEPT;
-- 부서번호는 E,D 부서명은 D, 사원명 E, 직종명 E, 급여 E
-- 칼럼이 두 테이블에 나눠져있으므로 JOIN해야한다.
-- ON은 결합조건, WHERE은 선택조건
SELECT D.DEPTNO, D.DNAME, E.ENAME, E.JOB, E.SAL   
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO                   -- ON 결합조건     
AND E.JOB IN ('MANAGER', 'CLERK');  -- WHERE 선택조건
-- 두 테이블 간 중복 컬럼인 DEPTNO를 하나의 테이블에서 가져오겠다고 명시하지 않으면
-- 테이블이 겹쳐져서 에러가 난다.
-- 두 테이블 간 중복되는 칼럼에 대해 소속 테이블을 명시하는 경우
-- 부모 테이블의 컬럼을 참조할 수 있도록 처리해야 한다.
-- ※ 부모테이블인지 아닌지 어떻게 알 수 있을까?
-- 먼저, 부모 자식의 관계가 있는지 알려면 연결된 컬럼(연결고리컬럼)이 있는지 찾아야한다.

SELECT *
FROM EMP;   -- 자식테이블
SELECT *
FROM DEPT;  -- 부모테이블

-- EMP 테이블에서는 하나의 부서번호가 여러개여도 되지만
-- DEPT 테이블에서는 부서번호가 하나만 가져야한다.
-- EMP : 1 대 다
-- DEPT : 1 대 1
-- 따라서, DEPT가 부모테이블 EMP가 자식테이블
SELECT D.DEPTNO, D.DNAME, E.ENAME, E.JOB, E.SAL  
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;
-- 이렇게 칼럼명마다 테이블을 명시해주는게 더 빠름.
-- 테이블을 명시해주면 오라클이 테이블을 왔다갔다 할 필요없어짐

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

-- EMP 테이블의 데이터를 다음과 같이 조회하라
------------------------------------------------------------
-- 사원번호 사원명 직종명 관리자번호 관리자명 관리자직종명
--   7369   SMITH  CLERK     7902      FORD     ANALYST
SELECT E1.EMPNO 사원번호, E1.ENAME 사원명, E1.JOB 직종명, E1.MGR 관리자번호, E2.ENAME 관리자명, E2.JOB 관리자직종명
FROM EMP E1 LEFT JOIN EMP E2
ON E1.MGR = E2.EMPNO
ORDER BY 1;
/*
7369	SMITH	CLERK	    7902	FORD	ANALYST
7499	ALLEN	SALESMAN	7698	BLAKE	MANAGER
7521	WARD	SALESMAN	7698	BLAKE	MANAGER
7566	JONES	MANAGER	    7839	KING	PRESIDENT
7654	MARTIN	SALESMAN	7698	BLAKE	MANAGER
7698	BLAKE	MANAGER	    7839	KING	PRESIDENT
7782	CLARK	MANAGER	    7839	KING	PRESIDENT
7788	SCOTT	ANALYST	    7566	JONES	MANAGER
7839	KING	PRESIDENT	(null)	(null)	(null)
7844	TURNER	SALESMAN	7698	BLAKE	MANAGER
7876	ADAMS	CLERK	    7788	SCOTT	ANALYST
7900	JAMES	CLERK	    7698	BLAKE	MANAGER
7902	FORD	ANALYST	    7566	JONES	MANAGER
7934	MILLER	CLERK	    7782	CLARK	MANAGER
*/
1992 코드로 보기

SELECT E1.EMPNO 사원번호, E1.ENAME 사원명, E1.JOB 직종명, E1.MGR 관리자번호, E2.ENAME 관리자명, E2.JOB 관리자직종명
FROM EMP E1,  EMP E2
WHERE E1.MGR = E2.EMPNO(+)
ORDER BY 1;
/*
/*
7369	SMITH	CLERK	    7902	FORD	ANALYST
7499	ALLEN	SALESMAN	7698	BLAKE	MANAGER
7521	WARD	SALESMAN	7698	BLAKE	MANAGER
7566	JONES	MANAGER	    7839	KING	PRESIDENT
7654	MARTIN	SALESMAN	7698	BLAKE	MANAGER
7698	BLAKE	MANAGER	    7839	KING	PRESIDENT
7782	CLARK	MANAGER	    7839	KING	PRESIDENT
7788	SCOTT	ANALYST	    7566	JONES	MANAGER
7839	KING	PRESIDENT	(null)	(null)	(null)
7844	TURNER	SALESMAN	7698	BLAKE	MANAGER
7876	ADAMS	CLERK	    7788	SCOTT	ANALYST
7900	JAMES	CLERK	    7698	BLAKE	MANAGER
7902	FORD	ANALYST	    7566	JONES	MANAGER
7934	MILLER	CLERK	    7782	CLARK	MANAGER
*/
*/
-- ※ 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 에러발생
-- 칼럼이 겹치기때문에 어느 부모 테이블에서 가져올건지 명시해야한다.
NATURALJOINはOracleに対して「自分で接続先を探して、自分で両親の机を探してください」と言います.
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
*/
USING 이라는 것도 있다.

SELECT DEPTNO, DNAME, ENAME, SAL
FROM EMP JOIN DEPT
USING(DEPTNO);    ← DEPTNO를 이용해줘
データ・リカバリ
1. 데이터를 백업하는게 중요하다.

-- ※ TBL_SAWON 테이블 백업 (데이터 위주) → 각 테이블 간의 관계나 조약조건 등은 제외
CREATE TABLE TBL_SAWONBACKUP
AS
SELECT SANO, SANAME, JUBUN, HIREDATE, SAL
FROM TBL_SAWON;
--> Table TBL_SAWONBACKUP이(가) 생성되었습니다.
-- 데이터 활용.. 관리.. 여러 형태로 운용 중...
-- 그러다가 데이터 수정 할 일이 생길때

UPDATE TBL_SAWON
SET SANAME = '똘똘이';
COMMIT;
-- 이렇게하면 SANAME의 모든 데이터가 똘똘이로 변함.....
-- COMMIT을 해서 ROLLBACK로 안먹힘..
-- 데이터 복원(UPDATE) → 불완전복구
UPDATE TBL_SAWON
SET SANAME = (SELECT SANAME
              FROM TBL_SAWONBACKUP
              WHERE SANO = TBL_SAWON.SANO)
WHERE SANAME = '똘똘이';