-
[ SQL ] JOIN (문제풀이와 포괄조인)PROGRAMMING/SQL 2022. 4. 28. 15:00
하루입니다.
- 직원아이디, 직원이름, 직종제목, 급여, 급여등급, 소속부서명, 근무지도시명, 관리자이름을 조회하기
- E1 E1 J E1 S D L E2
SELECT E.EMPLOYEE_ID EMP_ID, E.FIRST_NAME EMP_NAME, J.JOB_TITLE EMP_JOB_TITLE, E.SALARY EMP_SALARY, S.GRADE EMP_GRADE, D.DEPARTMENT_NAME EMP_DEPT_NAME, L.CITY EMP_DEPT_CITY, M.FIRST_NAME MGR_NAME FROM EMPLOYEES E, EMPLOYEES M, JOBS J, SALARY_GRADE S, DEPARTMENTS D, LOCATIONS L WHERE E.JOB_ID = J.JOB_ID AND E.SALARY >= S.MIN_SALARY AND E.SALARY <= S.MAX_SALARY AND E.DEPARTMENT_ID = D.DEPARTMENT_ID AND D.LOCATION_ID = L.LOCATION_ID AND E.MANAGER_ID = M.EMPLOYEE_ID ORDER BY E.EMPLOYEE_ID;코드해석
FROM 총 5개의 테이블, 셀프조인까지 해서 6개의 테이블이 적힌다.
SELECT 직원의 아이디, 이름, 직종이름, 급여, 급여등급, 소속부서, 근무지도시명 / 매니저의 이름
WHERE 직원의 JOB_ID와 직종의 JOB_ID 컬럼같이 같은 행끼리 연결한다.
AND 직원의 SALARY가 등급의 MIN_SALARY이상, MAX_SALARY 이하인 행끼리 연결한다.
AND 직원의 DEPARTMENT_ID와 부서의 DEPARTMENT_ID가 같은 행끼리 연결한다.
AND 직원의 DEPARTMENT_ID와 부서의 DEPARTMENT_ID가 같은 행의 부서 LOCATION_ID와 소재지의 LOCATION_ID가 같은 행끼리 연결한다. (왜 이렇게 적냐면 직원과 장소 테이블은 연관키가 없어서 부서를 통해 연결되기 때문)
AND 직원의 MANAGER_ID와 관리자의 EMPLOYEE_ID가 같은 행끼리 연결한다.
ORDER BY 직원 아이디를 오름차순으로 정렬한다.- 결과는 총 105개의 행이 나온다.
- 하지만 총 직원은 107명 ...
- 왜 2명의 직원이 빠졌냐면 - 100번 STEVEN은 최고직원이라 상사가 NULL이다. 170번 KIMBERLY는 부서아이디가 NULL이다. 조인할 때 하나라도 값이 NULL이라면 조인되지 않기에 벌어진 불상사이다.
- 소외된 두 사람을 함께 조회하기 위해선 포괄조인을 사용해야 한다.
포괄조인
- 테이블을 조인했을 때 연결된 행이 없는 정보도 조회할 수 있게 하는 조인
- 한쪽 테이블에는 데이터가 있고, 다른쪽 테이블에는 데이터가 없는 경우에 데이터가 있는 쪽 테이블의 내용을 전부 조회하는 조인방법이다.
- 위에서 100번은 MANAGER_ID가, 170번은 DEPARTMENT_ID가 NULL이라 JOIN에 포함되지 못했다. 하지만 다른 정보들은 전부 있는 상황.
- 이런 상황에서 데이터가 없는 쪽에 NULL행을 추가해서 100번도 107번도 조회할 수 있게 하는 게 포괄조인이다.


- '모든' 직원아이디, 직원이름, 직종제목, 급여, 급여등급, 소속부서명, 근무지도시명, 관리자이름을 조회하기
- E1 E1 J E1 S D L E2
- NULL행을 추가할 곳에 (+)를 붙이면 된다. 왼쪽 오른쪽 상관 없지만 양쪽에 붙일 순 없다.
- 여기서는 직원테이블 부서아이디가 NULL이라서 부서테이블 부서아이디에 NULL을 더해주기 위해, 직원테이블의 매니저아이디가 NULL이라서 부서테이블 직원아이디에 NULL 더해주기 위해 (+)를 사용했다.
- 107명이 모두 조회된다!
- LOCATION_ID에는 왜 붙인 걸까?
SELECT E.EMPLOYEE_ID EMP_ID, E.FIRST_NAME EMP_NAME, J.JOB_TITLE EMP_JOB_TITLE, E.SALARY EMP_SALARY, S.GRADE EMP_GRADE, D.DEPARTMENT_NAME EMP_DEPT_NAME, L.CITY EMP_DEPT_CITY, M.FIRST_NAME MGR_NAME FROM EMPLOYEES E, EMPLOYEES M, JOBS J, SALARY_GRADE S, DEPARTMENTS D, LOCATIONS L WHERE E.JOB_ID = J.JOB_ID AND E.SALARY >= S.MIN_SALARY AND E.SALARY <= S.MAX_SALARY AND E.DEPARTMENT_ID = D.DEPARTMENT_ID(+) AND D.LOCATION_ID = L.LOCATION_ID(+) AND E.MANAGER_ID = M.EMPLOYEE_ID(+) ORDER BY E.EMPLOYEE_ID;- 밑의 그림을 보자.
- 178번의 E.부서아이디는 NULL이라 조인하면 조회되지 않는다. 조인에 포함하기 위해 D.부서에 NULL행을 추가했다.
- 178번 직원의 부서테이블 행은 모두 NULL이다.
- 이 상황에서 장소ID를 알기 위해 부서테이블의 장소ID와 장소테이블의 장소ID를 연결해야 한다.
- 하지만 178의 부서테이블 행은 모두 NULL ... 이대로 그냥 조인하면 또다시 누락될 것. NULL이니까.
- NULL과 장소ID를 연결하기 위해 (+)를 사용하여 178번의 장소테이블 행에도 NULL을 추가시킨다.
- 이렇게 하면 ID, NAME, DEPT_ID는 조회되고 나머지 값은 모두 NULL로 조회된다.

잘못된 정보에 대한 지적은 언제나 환영입니다.
복습 끝!
'PROGRAMMING > SQL' 카테고리의 다른 글
[ SQL ] 오라클 다중행함수(그룹함수) 와 GROUP_BY절 (0) 2022.04.29 [ SQL ] ORACLE의 데이터 타입 (0) 2022.04.28 [ SQL ] JOIN(등가조인 여러개 하기, 비등가조인, 셀프조인) (0) 2022.04.27 [ SQL ] 정규화와 JOIN (등가조인) (0) 2022.04.27 [ SQL ] 오라클 내장함수 2. 단일행함수의 숫자함수, 날짜함수 (0) 2022.04.27