본문 바로가기

Archived(CSE Programming)/SQL(Oracle)

SQL_JOIN

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