RDBMS 이기에 JOIN이 없을 수가 없음
현업에서도 반드시 필요한 기능
# JOIN의 종류
EQUAL 조인 / NOT EQUAL 조인
JOIN은 두 개 의 테이블을 통해 하나의 논리적 테이블을 구성한다 ?
> 편의상 이해를 위한 용어
# ORACLE JOIN
-- EQUL JOIN
SELECT EMP_NAME
, DEPT_NAME
FROM EMPLOYEE E
, DEPARTMENT D
WHERE E.DEPT_ID = D.DEPT_ID;
-- NOT EQUAL JOIN
SELECT EMP_NAME
, SALARY
, SLEVEL
FROM EMPLOYEE E
, SAL_GRADE S
WHERE E.SALARY BETWEEN S.LOWEST AND S.HIGHEST;
현업에서는 JOIN을 거는 FK 키를 주로 INDEX로 걸기에 NULL 로 JOIN이 걸리는 일이 거의 없다
ORACLE에서 OUTER JOIN은 (+)를 활용하기도 한다
-- EQUL JOIN
SELECT EMP_NAME
, DEPT_NAME
FROM EMPLOYEE E
, DEPARTMENT D
WHERE E.DEPT_ID(+) = D.DEPT_ID;
(+)가 붙어있는 테이블의 반대쪽 테이블 데이터를 전부 출력한다
ORACLE에서는 FULL OUTER JOIN (+) 개념이 없다!
# ANSI 표준 JOIN
JOIN 유형을 세분화
WHERE 절을 ON/USING으로 변경해주면 된다
USING 구문은 기준 컬럼 정의(같은 이름의 컬럼 정의)
-- ANSI 표준 JOIN
SELECT EMP_NAME
, DEPT_NAME
FROM EMPLOYEE E
INNER JOIN DEPARTMENT D USING(DEPT_ID);
-- ANSI 표준 NOT EQUAL JOIN
SELECT EMP_NAME
, SALARY
, SLEVEL
FROM EMPLOYEE E
JOIN SAL_GRADE S ON (E.SALARY BETWEEN S.LOWEST AND S.HIGHEST);
-- ANSI 표준 EQUAL JOIN ON
SELECT DEPT_NAME
, LOC_DESCRIBE
FROM DEPARTMENT D
JOIN LOCATION L ON D.LOC_ID = L.LOCATION_ID;
JOIN 키를 기준으로 LEFT / RIGHT / FULL 중 어느 테이블의 모든 것을 출력할 지(기준 테이블)
-- ANSI 표준 JOIN
SELECT EMP_NAME
, DEPT_NAME
FROM EMPLOYEE E
LEFT JOIN DEPARTMENT D USING(DEPT_ID);
-- ANSI 표준 JOIN
SELECT EMP_NAME
, DEPT_NAME
FROM EMPLOYEE E
RIGHT JOIN DEPARTMENT D USING(DEPT_ID);
-- ANSI 표준 JOIN
SELECT EMP_NAME
, DEPT_NAME
FROM EMPLOYEE E
FULL JOIN DEPARTMENT D USING(DEPT_ID);
CF. NATURAL JOIN은 이름이 같은 외래키와 기본키의 컬럼을 기준으로 알아서 JOIN 해주는 것이다
SELECT 절에 SELECT 스칼라 서브 쿼리
FROM 절에 INLINE 뷰
WHERE, HAVING 절 서브 쿼리
서브 쿼리가 길어지면 성능보장이 힘들어진다!
CF. USING 구문을 사용하는 곳에 별칭을 사용할 수 없다!
SELF JOIN -> 자기 자신의 테이블에서 외래키와 기본키 통해 JOIN 가능!
-- SELF JOIN
SELECT E.EMP_NAME AS 직원
, M.EMP_NAME AS 관리자
FROM EMPLOYEE E
JOIN EMPLOYEE M ON E.MGR_ID = M.EMP_ID
ORDER BY 1;
-- SELF JOIN
SELECT E.EMP_NAME AS 직원
, M.EMP_NAME AS 관리자
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE M ON E.MGR_ID = M.EMP_ID
ORDER BY 1;
-- 재귀적 SELF JOIN
SELECT E.EMP_NAME AS 직원
, M.EMP_NAME AS 관리자
, S.EMP_NAME AS "상위 관리자"
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE M ON E.MGR_ID = M.EMP_ID
LEFT JOIN EMPLOYEE S ON M.MGR_ID = S.EMP_ID
ORDER BY 1;
논리적 순서에 따라 어떻게 JOIN을 할 지 결정
-- 3중 JOIN
SELECT E.EMP_NAME
, J.JOB_TITLE
, D.DEPT_NAME
FROM EMPLOYEE E
JOIN JOB J ON E.JOB_ID = J.JOB_ID
JOIN DEPARTMENT D ON E.DEPT_ID = D.DEPT_ID;
-- 5중 JOIN
SELECT E.EMP_NAME
, E.SALARY
, S.SLEVEL
, J.JOB_TITLE
, D.DEPT_NAME
, L.LOC_DESCRIBE
, C.COUNTRY_NAME
FROM EMPLOYEE E
JOIN SAL_GRADE S ON E.SALARY BETWEEN S.LOWEST AND S.HIGHEST
JOIN JOB J ON E.JOB_ID = J.JOB_ID
JOIN DEPARTMENT D ON E.DEPT_ID = D.DEPT_ID
JOIN LOCATION L ON D.LOC_ID = L.LOCATION_ID
JOIN COUNTRY C ON L.COUNTRY_ID = C.COUNTRY_ID;
-- 5중 JOIN 조건 추가
SELECT E.EMP_NAME
, E.SALARY
, S.SLEVEL
, J.JOB_TITLE
, D.DEPT_NAME
, L.LOC_DESCRIBE
, C.COUNTRY_NAME
FROM EMPLOYEE E
JOIN SAL_GRADE S ON E.SALARY BETWEEN S.LOWEST AND S.HIGHEST
JOIN JOB J ON E.JOB_ID = J.JOB_ID
JOIN DEPARTMENT D ON E.DEPT_ID = D.DEPT_ID
JOIN LOCATION L ON D.LOC_ID = L.LOCATION_ID
JOIN COUNTRY C ON L.COUNTRY_ID = C.COUNTRY_ID
WHERE J.JOB_TITLE = '대리'
AND LOC_DESCRIBE LIKE '아시아%';
'Archived(CSE Programming) > SQL(Oracle)' 카테고리의 다른 글
SQL_DDL (0) | 2020.01.23 |
---|---|
SQL_SET_SubQuery (0) | 2020.01.22 |
SQL_Additional_SELECT_그룹 함수 (0) | 2020.01.21 |
SQL_Additional_SELECT_단일 행 함수 (0) | 2020.01.20 |
SQL_SELECT (0) | 2020.01.20 |