1. GROUP BY : 그룹을 묶어줄 기준을 제시할 수 있는 구문
- 여러개의 값들을 그룹별로 나눠서 처리할 목적으로 사용
-- 전체 사원의 총 급여합
SELECT SUM(SALARY) FROM EMPLOYEE;
-- 각 부서별 총 급여합
SELECT DEPT_CODE, SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE;
-- 전체 사원 수
SELECT COUNT(*)
FROM EMPLOYEE;
-- 각 부서별 사원 수
SELECT DEPT_CODE, COUNT(*)
FROM EMPLOYEE
GROUP BY DEPT_CODE;
-- 각 부서별 총 급여 합 부서별로 오름차순 정렬해서 조회
SELECT DEPT_CODE, SUM(SALARY) --3. SELECT절
FROM EMPLOYEE --1. FROM절
GROUP BY DEPT_CODE --2. GROUP BY절
ORDER BY DEPT_CODE; --4. ORDER BY절
-- 성별 별 사원 수
SELECT DECODE(SUBSTR(EMP_NO, 8, 1), 1, '남자', 2, '여자') "성별", COUNT(*)
FROM EMPLOYEE
GROUP BY SUBSTR(EMP_NO, 8, 1);
-- 부서별 평균 급여 300만원 이상인 부서들만 조회
SELECT DEPT_CODE, ROUND(AVG(SALARY))
FROM EMPLOYEE
--WHERE AVG(SALARY) >= 3000000
GROUP BY DEPT_CODE;
-->GROUP BY절이 WHERE절 보다 실행이 빠르기 때문 -> GROUP BY절과 WHERE절 함께 사용불가
1-2. HAVING : 그룹에 대한 조건을 제시하고자 할 때 사용되는 구문
(대부분의 경우 그룹함수를 가지고 조건 제시)
SELECT DEPT_CODE, ROUND(AVG(SALARY))
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING AVG(SALARY) >= 3000000;
--각 직급별 총 급여 합이 1000만원 이상인 직급코드, 급여합 조회
SELECT JOB_CODE, SUM(SALARY)
FROM EMPLOYEE
GROUP BY JOB_CODE
HAVING SUM(SALARY) >= 10000000;
--각 부서별 보너스를 받는 사원이 없는 부서만(DEPT_CODE)
SELECT DEPT_CODE
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING COUNT(BONUS) = 0; -->HAVING절엔 그룹함수를 많이 씀
< 실행 순서 >
5: SELECT * / 조회하고자 하는 컬럼 / 산술연산 / 함수식 "별명"
1: FROM 조회하고자 하는 테이블
2: WHERE 조건식
3: GROUP BY 그룹기준에 해당하는 컬럼명 / 함수식
4: HAVING 그룹함수식에 대한 조건식
6: ORDER BY 정렬기준에 대한 컬럼명 / 별칭 / 컬럼 순번 ASC, DESC NULL F/ NULL L
SELECT EMP_ID "숫자", EMP_NAME
FROM EMPLOYEE
WHERE EMP_ID >= 215
ORDER BY "숫자" DESC;
2. JOIN : 두 개 이상의 테이블에서 데이터를 같이 조회하고자 할 때 사용되는 구문
조회결과는 하나의 결과물(RESULT SET)로 나옴
- 관계형 데이터베이스에서는 최소한의 데이터로 각각의 테이블에서 데이터를 보관하고 있음
-> 관계를 맺어본 적이 없음
- JOIN구문을 이용해서 여러 개의 테이블 간 "관계"를 맺어서 조회하는 법을 공부할 것임
- 무작정 JOIN을 사용해서 조회하는 것이 아니라 테이블 간 "연결고리"에 해당하는 컬럼을 매칭시켜야 함.
- JOIN은 크게 "오라클 전용 구문"과 "ANSI(미국 국립 표준협회) 구문"으로 나뉜다.
오라클 전용 구문 | ANSI(오라클 + 다른 DBMS) 구문 |
등가조인 (EQUL JOIN) 포괄조인 (LEFT OUTER) (RIGHT OUTER) |
내부조인 (INNER JOIN) 외부조인 (OUTER JOIN) 왼쪽 외부조인 (LEFT OUTER JOIN) 오른쪽 외부조인 (RIGHT OUTER JOIN) 전체 외부조인 (FULL OUTER JOIN) => 오라클에선 불가 |
카테시안 곱(CARTESIAN PRODUCT) | 교차조인(CROSS JOIN) |
자체조인 (SELF JOIN) |
1) 등가 조인 (EQUAL JOIN) / 내부 조인(INNER JOIN)
: 연결시키는 컬럼의 값이 일치하는 행들만 조인돼서 조회 (==일치하지 않는 값들은 조회에서 제외)
* 오라클 전용구문
- FROM절에 조회하고자 하는 테이블들을 나열(,)
- WHERE절에 매칭시킬 컬럼명(연결고리)에 대한 조건을 제시함
-- 전체 사원들의 사번, 사원명, 부서코드, 부서명을 같이 조회
--1) 연결할 두 컬럼명이 다른 경우
--EMPLOYEE = "DEPT_CODE" / DEPARTMENT = "DEPT_ID"
SELECT DEPT_CODE FROM EMPLOYEE;
SELECT DEPT_ID FROM DEPARTMENT;
SELECT COUNT(*) FROM DEPARTMENT;
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT; --> 23행 * 9행 = 207행 => 의도한 값이 아님(카테시안곱이 실행됨)
SELECT EMP_ID, EMP_NAME, /*DEPT_CODE, DEPT_ID,*/ DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID; --> 연결고리
--> 하지만, 부서코드가 NULL인 행들은 조회되지 않음.(일치하지 않기 때문)
-- 사번, 사원명, 직급코드, 직급명
--2) 연결할 두 컬럼명이 같은 경우
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE, JOB
WHERE JOB_CODE = JOB_CODE;
--에러(ambiguously: 애매하다, 모호하다): 어떤 테이블의 컬럼인지 애매모호
--방법 1: 테이블명을 이용하는 방법
SELECT EMP_ID, EMP_NAME, EMPLOYEE.JOB_CODE, JOB_NAME
FROM EMPLOYEE, JOB
WHERE EMPLOYEE.JOB_CODE = JOB.JOB_CODE;
--방법 2: 테이블의 별칭 사용( 각 테이블마다 별칭 부여 )
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, JOB_NAME
FROM EMPLOYEE E, JOB J
WHERE E.JOB_CODE = J.JOB_CODE;
* ANSI 구문
- FROM절에 기준테이블 하나 기술
- 그 뒤에 JOIN절에 같이 조회하고자하는 테이블 기술(매치이킬 컬럼에 대한 조건도 기술)
- USING / ON
--사번, 사원명, 부서코드, 부서명
--1. 연결할 두 컬럼명이 다른 경우
--EMPLOYEE - DEPT_CODE / DEPARTMENT - DEPT_ID
--무조건 ON구문만 사용함(USING은 사용 못함)
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
--사번, 사원명, 직급코드, 직급명
--2. 연결할 두 컬럼명이 같은 경우
-- EMPLOYEE - JOB_CODE / JOB - JOB_CODE
-- ON, USING구문
-- 2_1. ON 구문 이용 : AMBIGUOUSLY가 발생할 수 있기 때문에 명시!!!
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, JOB_NAME
FROM EMPLOYEE E
JOIN JOB J ON(E.JOB_CODE = J.JOB_CODE);
--2_2.USING구문 이용: ambiguously 발생 X
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
JOIN JOB USING(JOB_CODE);
+ NATURAL JOIN (자연조인)
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
NATURAL JOIN JOB;
-운좋게 두 개의 테이블에 일치하는 칼럼이 유일하게 딱 한 개 => 알아서 매칭됨
* 추가적인 조건제시
--사번, 이름, 급여, 직급 이름
--직급이 대리인 사원들의 정보만 조회
--> 오라클 전용 구문
SELECT
EMP_ID,
EMP_NAME,
SALARY,
JOB_NAME
FROM
EMPLOYEE E,
JOB J
WHERE
E.JOB_CODE = J.JOB_CODE
AND
J.JOB_NAME = '대리';
--> 협업 시 가독성을 높이기 위해 보통 컬럼이나 조건 다 내려서 씀
--> ANSI구문
SELECT EMP_ID, EMP_NAME, SALARY, JOB_NAME
FROM EMPLOYEE
JOIN JOB USING(JOB_CODE)
WHERE JOB_NAME = '대리';
실습1. 부서가 '인사관리부'인 사원들의 사번, 사원명, 보너스를 조회
-->ORACLE
SELECT EMP_ID, EMP_NAME, BONUS
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
WHERE DEPT_TITLE = '인사관리부';
-->ANSI
SELECT EMP_ID, EMP_NAME, BONUS
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID
AND DEPT_TITLE = '인사관리부';
실습2. 부서가 '총무부'가 아닌 사원들의 사원명, 급여, 입사일을 조회
-->ORACLE
SELECT EMP_NAME, SALARY, HIRE_DATE
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
WHERE DEPT_TITLE = '총무부';
-->ANSI
SELECT EMP_NAME, SALARY, HIRE_DATE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID
AND DEPT_TITLE = '총무부';
실습3. 보너스를 받는 사원들의 사번, 사원명, 보너스 부서명 조회
-->ORACLE
SELECT EMP_NO, EMP_NAME, BONUS
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
WHERE BONUS IS NOT NULL;
-->ANSI
SELECT EMP_NO, EMP_NAME, BONUS
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID
AND BONUS IS NOT NULL;
실습4. DEPARTMENT 테이믈, LOCATION테이블을 참고해서 부서코드, 부서명, 지역코드, 지역명(LOCAL_NAME) 조회
-->ORACLE
SELECT DEPT_ID, DEPT_TITLE, LOCAL_CODE, LOCAL_NAME
FROM DEPARTMENT, LOCATION
WHERE LOCAL_CODE = LOCATION_ID;
-->ANSI
SELECT DEPT_ID, DEPT_TITLE, LOCAL_CODE, LOCAL_NAME
FROM DEPARTMENT
JOIN LOCATION ON (LOCAL_CODE = LOCATION_ID);
* 등가조인 / 내부조인의 단점 : 등가조인 / 내부조인 : 일치하지 않는 행들은 애초에 조회되지 않음
-> 문제가 생길 여지가 있음 (모든 행을 조회하지 않는다)
2) 포괄조인 / 외부조인(OUTER JOIN)
테이블 간의 JOIN 시 일치하지 않는 행도 포함시켜서 조회 가능
단, 반드시 LEFT / RIGHT를 지정해야 함(기준이 되는 테이블 지정)
전체 사원들의 사원명, 급여, 부서명 조회시,
EMPLOYEE == DEPT_CODE가 NULL인 두 명의 사원도 조회한다면?
DEPARTMENT == 부서에 배정된 사원이 없는 부서(D3, D4, D7)조회한다면?
1) LEFT (OUTER) JOIN : 두 테이블 중 왼편에 기술된 테이블을 기준으로 JOIN
즉, 뭐가 되었든 간에 왼편에 기술된 테이블에 데이터는 무조건 조회(NULL) (일치하는 게 없어도 조회하겠다)
-->ANSI구문
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE
LEFT /*OUTER*/JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);
--EMPLOYEE테이블을 기준으로 조회 했기 때문에 EMPLOYEE에 존재하는 데이터가 뭐든간에 무조건 조회되게끔 한다.
-->ORACLE 구문
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID(+);
--내가 기준으로 삼을 테이블의 컬럼명 반대 항에 (+)라고 적기
2) RIGHT (OUTER) JOIN : 두 테이블의 오른편에 기술된 테이블을 기준으로 JOIN
-->ANSI
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE
RIGHT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);
-->ORACLE
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID;
3) FULL (OUTER) JOIN : 두 테이블이 가진 모든 행을 조회
--> ANSI
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE
FULL OUTER JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID); --> FULL 은 OUTER까지 적기
--> ORACLE (에러남 : ONLY ONE OUT-JOINED TABLE)
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID(+);
3. 카데시안 곱( CARTESIAN PRODUST) / 교차 조인(CROSS JOIN)
모든 테이블의 각 행들이 서로서로 매핑된 데이터가 조회됨(곱집합)
두 테이블의 행들이 모두 곱해진 조합 출력
=> 방대한 데이터 출력
=> 과부화의 위험
--사원명, 부서명
-->ORACLE
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT;
-->ANSI
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
CROSS JOIN DEPARTMENT;
4. 비등가조인(NON EQUAL JOIN)
'='를 사용하지 않는 조인문
지정해주는 컬럼값이 일치하는 경우가 아닌 "범위"에 포함되는 경우 매칭
--사원명, 급여
SELECT EMP_NAME, SALARY
FROM EMPLOYEE;
SELECT * FROM SAL_GRADE;
SELECT * FROM EMPLOYEE;
--사원명, 급여, 급여등급 (SAL_LEVEL)
-->ORACLE
SELECT EMP_NAME, SALARY, S.SAL_LEVEL
FROM EMPLOYEE E, SAL_GRADE S
WHERE SALARY BETWEEN MIN_SAL AND MAX_SAL;
-->ANSI(ON)
SELECT EMP_NAME, SALARY, S.SAL_LEVEL
FROM EMPLOYEE E
JOIN SAL_GRADE S ON (SALARY BETWEEN MIN_SAL AND MAX_SAL);
5. 자체조인(SELF JOIN)
같은 테이블을 다시 한 번 조인하는 경우 자기 자신의 테이블과 조인을 맺는다.
SELECT EMP_ID "사원 사번", EMP_NAME "사원명", SALARY "사원 급여", MANAGER_ID "사수사번"
FROM EMPLOYEE;
SELECT * FROM EMPLOYEE; --사원에 대한 정보 도출형 테이블
--MANAGER_ID
SELECT * FROM EMPLOYEE; --사수에 대한 정보 도출용 테이블
--EMP_ID
--사원사번, 사원명, 사원부서코드 , 사원급여
--사수사번, 사수명, 사수부서코드 , 사수급여
SELECT E.EMP_ID "사원번호", E.EMP_NAME "사원이름", E.DEPT_CODE "부서코드", E.SALARY "사원급여",
M.EMP_ID "사수번호", M.EMP_NAME "사수이름", M.DEPT_CODE"부서코드", M.SALARY "사수급여"
FROM EMPLOYEE E, EMPLOYEE M
WHERE E.MANAGER_ID = M.EMP_ID(+) ; --> LEFT JOIN
--ANSI
SELECT E.EMP_ID "사원번호", E.EMP_NAME "사원이름", E.DEPT_CODE "부서코드", E.SALARY "사원급여",
M.EMP_ID "사수번호", M.EMP_NAME "사수이름", M.DEPT_CODE"부서코드", M.SALARY "사수급여"
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE M ON (E.MANAGER_ID = M.EMP_ID) ;
--사원사번, 사원명, 사원 부서코드 , 사원부서명, 사원 급여
--사수사번, 사수명, 사수부서코드, 사수부서명, 사수 급여
SELECT E.EMP_ID "사원번호", E.EMP_NAME "사원이름", D1.DEPT_TITLE "부서명", E.SALARY "사원급여",
M.EMP_ID "사수번호", M.EMP_NAME "사수이름", D2.DEPT_TITLE "부서명", M.SALARY "사수급여"
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE M ON(E.MANAGER_ID = M.EMP_ID)
JOIN DEPARTMENT D1 ON(E.DEPT_CODE = D1.DEPT_ID)
JOIN DEPARTMENT D2 ON(M.DEPT_CODE = D2.DEPT_ID);
6. 집합연산자 (SET OPERATOR)
여러 개의 쿼리문을 가지고 하나의 쿼리문으로 만드는 연산자
- UNION : 합집합(두 쿼리문을 수행한 결과값을 더한 후 중복되는 부분은 한 번 뺀 것)
- UNION ALL : 합집합+교집합 (두 쿼리문을 수행한 결과값을 무조건 더함, 즉 합집합에서 중복제거를 하지 않은것 )
=> 중복된 결과가 두 번 조회될 수 있음
- INTERSECT : 교집합(두 쿼리문을 수행한 결과값의 중복된 결과값 부분) AND
- MINUS : 차집합(선행 쿼리문 결과값 - 후행 쿼리문 결과값)
아래 식을 집합연산자를 통해 이용해보면?
--부서코드가 D5인 사원들만 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5'; --> 6명 (박나라, 하이유, 김해술, 심봉선, 윤은해, 대북혼)
-- 급여가 300만원 초과인 사원들만 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000; --> 8명(선동일, 송종기, 노옹철, 유재식, 정중하, 심봉선, 대북혼, 전지연)
1) UNION( 합집합 - 두 쿼리문 수행한 결과값을 더하지만 중복되는 결과는 한 번만 조회 )
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5'
UNION
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000; --> 12명 조회 (6명 + 8명 -2명)
--두 쿼리의 SELECT절이 같아야 한다.
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5' OR SALARY > 3000000;
--OR연산자로 두 개의 조건을 엮어서 조회하면 결과는 동일
--각 부서별 급여합 조회(부서코드, 부서별 급여합)
--UNION을 이용해서
SELECT SUM(SALARY)
FROM EMPLOYEE
WHERE DEPT_CODE = 'D1'
UNION
SELECT SUM(SALARY)
FROM EMPLOYEE
WHERE DEPT_CODE = 'D2'
UNION
SELECT SUM(SALARY)
FROM EMPLOYEE
WHERE DEPT_CODE = 'D3'
UNION
SELECT SUM(SALARY)
FROM EMPLOYEE
WHERE DEPT_CODE = 'D4';
--> 각 부서별로 WHERE 절을 이용해서 하나한 UNION으로 합쳐줘야 한다.
--> GROUP BY를 이용해서 쉽게 해결 가능
SELECT DEPT_CODE, SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE;
2) UNION ALL: 여러개의 쿼리 결과를 무조건 더하는 연산자(중복값이 여러 개 들어갈 수 있음)
-> 다른 것들은 다른 방법으로 대체 가능하지만, UNION ALL은 불가능
--UNION ALL
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5'
UNION ALL
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000; --> 14명조회
3) INTERSECT (교집합 - 여러 쿼리 결과의 중복된 결과만을 조회)
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5'
INTERSECT
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000; --> 2명조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5' AND SALARY > 3000000;
--> AND로 대체 가능
4) MINUS (차집합-선행쿼리 결과에 후행쿼리 결과를 뺀 나머지)
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5'
MINUS
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000; --> 4명조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5' AND SALARY <= 3000000;
--> 부등호를 바꿔 가능
7. 다중 JOIN
-- 사번, 사원명, 부서명, 직급명
SELECT * FROM EMPLOYEE; -- DEPT_CODE JOB_CODE
SELECT * FROM DEPARTMENT; --DEFT_ID
SELECT * FROM JOB; -- JOB_CODE
--ORACLE
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
JOIN JOB USING(JOB_CODE);
--ANSI
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE E, DEPARTMENT, JOB J
WHERE DEPT_CODE = DEPT_ID(+)
AND E.JOB_CODE = J.JOB_CODE;
-- 사번, 사원명, 부서명, 직급명, 지역명
--ANSI
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, LOCAL_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
LEFT JOIN JOB USING(JOB_CODE)
LEFT JOIN LOCATION ON(LOCATION_ID = LOCAL_CODE);
--ORACLE
SELECT EMP_ID, EMP_NAME, DEPT_TITLE, LOCAL_NAME
FROM EMPLOYEE E, DEPARTMENT, JOB J, LOCATION
WHERE DEPT_CODE = DEPT_ID(+)
AND E.JOB_CODE = J.JOB_CODE
AND LOCATION_ID = LOCAL_CODE(+);
-- 다중 JOIN할 때 순서 중요(LOCATION 테이블이 DEPARTMENT테이블보다 먼저 조인되면 오류)
--사원명, 부서명, 직급명, 근무지역명, 근무국가명, 급여등급
--EMPLOYEE, DEPARTMENT,
SELECT * FROM EMPLOYEE; --DEPT_CODE JOB_CODE SALARY
SELECT * FROM DEPARTMENT;--DEPT_ID LOCATION_ID
SELECT * FROM JOB; -- LOCAL_CODE
SELECT * FROM LOCATION;-- NATIONAL_CODE JOB_CODE
SELECT * FROM NATIONAL;-- NATIONAL_CODE
SELECT * FROM SAL_GRADE; -- MIN_SAL, MAX_SAL
SELECT
E.EMP_ID "사번",
D.DEPT_TITLE "부서명",
J.JOB_NAME "직급명",
L.LOCAL_NAME "근무지역명",
N.NATIONAL_NAME "근무국가명",
S.SAL_LEVEL "급여등급"
FROM
EMPLOYEE E
JOIN
DEPARTMENT D ON(E.DEPT_CODE = D.DEPT_ID)
JOIN
LOCATION L ON(D.LOCATION_ID = L.LOCAL_CODE)
JOIN
JOB J ON(E.JOB_CODE = J.JOB_CODE)
JOIN
NATIONAL N ON(L.NATIONAL_CODE = N.NATIONAL_CODE)
JOIN
SAL_GRADE S ON(E.SALARY BETWEEN MIN_SAL AND MAX_SAL);