-- 비등가조인 실습을 위한 테이블 생성
CREATE TABLE JOB_GRADES (
   GRA CHAR(1NOT NULL PRIMARY KEY,
   LOWEST_SALARY NUMBER(7),
   HIGHEST_SALARY NUMBER(7)
);
 
 
INSERT INTO JOB_GRADES (GRA, LOWEST_SALARY, HIGHEST_SALARY) VALUES('A'1000,    2999);
INSERT INTO JOB_GRADES (GRA, LOWEST_SALARY, HIGHEST_SALARY) VALUES('B'3000,    5999);
INSERT INTO JOB_GRADES (GRA, LOWEST_SALARY, HIGHEST_SALARY) VALUES('C'6000,    9999);
INSERT INTO JOB_GRADES (GRA, LOWEST_SALARY, HIGHEST_SALARY) VALUES('D'1000014999);
INSERT INTO JOB_GRADES (GRA, LOWEST_SALARY, HIGHEST_SALARY) VALUES('E'1500024999);
INSERT INTO JOB_GRADES (GRA, LOWEST_SALARY, HIGHEST_SALARY) VALUES('F'2500040000);
COMMIT;
 
-- 비등가 조인
-- = 연산자가 아닌 다른 연산자를 사용해서 조인 조건을 정의하는 조인
 
-- 사원의 이름, 사원의 급여, 급여 등급을 조회하기
-- 등호(=)를 사용하는 것이 아니라, 급여가 최소 급여와 최대 급여 사이에 해당하는 등급 관련 행이 조인되어야 함.
 
SELECT A.FIRST_NAME, A.SALARY, B.GRA
FROM EMPLOYEES A, JOB_GRADES B
WHERE A.SALARY >= B.LOWEST_SALARY
AND A.SALARY <= B.HIGHEST_SALARY
ORDER BY A.SALARY DESC;
 
-- 포괄조인(아우터조인:OUTER JOIN)
-- 포괄 조인을 사용하면 조인 조건을 만족하지 않는 행도 조회된다.
-- 포괄 조인 연산자는 +
 
-- 사원 이름, 부서 아이디, 부서 이름 조회하기
SELECT A.FIRST_NAME, A.DEPARTMENT_ID, B.DEPARTMENT_NAME
FROM EMPLOYEES A, DEPARTMENTS B
WHERE A.DEPARTMENT_ID = B.DEPARTMENT_ID(+);
 
-- 부서 아이디, 부서 이름, 부서 담당자 아이디, 부서 담당자 이름, 부서 담당자 직종 아이디를 조회하기
SELECT D.DEPARTMENT_ID, D.DEPARTMENT_NAME, D.MANAGER_ID, E.FIRST_NAME, E.JOB_ID
FROM DEPARTMENTS D, EMPLOYEES E
WHERE D.MANAGER_ID = E.EMPLOYEE_ID(+)
ORDER BY D.DEPARTMENT_ID;
 
-- 부서 아이디, 부서 이름, 부서 담당자 아이디, 부서 담당자 이름, 그 부서의 주소를 조회하기
SELECT A.DEPARTMENT_ID, A.DEPARTMENT_NAME, A.MANAGER_ID, B.FIRST_NAME, C.CITY
FROM DEPARTMENTS A, EMPLOYEES B, LOCATIONS C
WHERE A.MANAGER_ID = B.EMPLOYEE_ID(+)
AND A.LOCATION_ID = C.LOCATION_ID
ORDER BY A.DEPARTMENT_ID;
 
-- 사원의 이름, 사원의 급여, 급여 등급, 소속 부서 이름을 조회하기(107명이 조회되어야 함)
SELECT A.FIRST_NAME, A.SALARY, B.GRA, C.DEPARTMENT_NAME
FROM EMPLOYEES A, JOB_GRADES B, DEPARTMENTS C
WHERE A.DEPARTMENT_ID = C.DEPARTMENT_ID(+)
AND A.SALARY >= B.LOWEST_SALARY
AND A.SALARY <= B.HIGHEST_SALARY
ORDER BY A.FIRST_NAME ASC;
 
-- 셀프 조인
-- 자기 자신의 테이블과 다시 조인을 해야하는 경우 사용된다.
-- 상하관계(재귀관계)가 있는 조직도, 메뉴 구성 정보, 카테고리 구성 정보 등이 셀프 조인을 통해서
-- 필요한 데이터를 조회할 수 있는 경우이다.
-- 같은 테이블을 서로 조인하기 때문에 테이블마다 적절한 역할을 부여해서 조인에 참여시켜야 한다.
 
-- 100번 부서에 근무하는 사원의 아이디, 사원의 이름, 그 사원의 상사 아이디, 그 사원의 상사 이름을 조회하기
SELECT A.EMPLOYEE_ID 직원_아이디, A.FIRST_NAME 직원_이름, B.EMPLOYEE_ID 상사_아이디, B.FIRST_NAME 상사_이름
FROM EMPLOYEES A, EMPLOYEES B
WHERE A.MANAGER_ID = B.EMPLOYEE_ID AND A.DEPARTMENT_ID = 100;
 
-- 90번 부서에 근무하는 매니저에게 보고하는 직원들의 아이디, 이름, 급여, 부서명을 조회하기
SELECT 직원.EMPLOYEE_ID, 직원.FIRST_NAME, 직원.SALARY, 부서.DEPARTMENT_NAME
FROM EMPLOYEES 매니저, EMPLOYEES 직원, DEPARTMENTS 부서
WHERE 부서.DEPARTMENT_ID = 직원.DEPARTMENT_ID
AND 매니저.EMPLOYEE_ID = 직원.MANAGER_ID
AND 매니저.DEPARTMENT_ID = 90;
 
-- 다중행 함수(그룹함수)
-- 그룹함수는 행 집합(행 그룹)에 작용해서 그룹 당 하나의 결과를 생성한다.
-- 행 집합은 테이블 전체 행일 수도 있고,
-- 테이블에서 특정 컬럼의 값이 동일한 것끼리 그룹화된 행일수도 있다.
-- 그룹함수
-- COUNT(*), COUNT(컬럼명) 행의 개수, *일 때는 모든 행의 개수, 컬럼명을 지정하면 NULL이 아닌 행의 개수
--SUM(컬럼명) 합계를 계산, NULL은 무시한다.
--AVG(컬럼명) 평균을 계산, NULL은 무시
-- MIN(컬럼명) 최솟값을 계산, NULL 무시
-- MAX(컬럼명) 최댓값을 계산, NULL 무시
-- VARIANCE(컬럼명) 분산을 계산, NULL 무시
-- STDDEV(컬럼명) 
 
-- COUNT(*)
-- 직원의 수를 조회하기
SELECT COUNT(*)
FROM EMPLOYEES;
 
-- 커미션을 받는 직원의 수 조회하기
SELECT COUNT(*)
FROM EMPLOYEES
WHERE COMMISSION_PCT IS NOT NULL;
 
-- COUNT(컬럼명)은 해당 컬럼의 값이 NULL이 아닌 행의 개수만 센다.
SELECT COUNT(COMMISSION_PCT)
FROM EMPLOYEES;
 
-- 80번 부서에 소속된 사원들의 급여 총합을 조회하기
SELECT SUM(SALARY)
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 80;
 
-- 커미션의 평균을 조회하기
SELECT AVG(COMMISSION_PCT)
FROM EMPLOYEES;
-- 또는
SELECT SUM(COMMISSION_PCT/35)
FROM EMPLOYEES;
-- NULL이 아닌 것만 갖고 계산이 된다.
 
-- 최저급여를 조회하기
SELECT FIRST_NAME
FROM EMPLOYEES
WHERE SALARY = (SELECT MIN(SALARY)
                        FROM EMPLOYEES);
 
-- 커미션을 받는 직원들의 이름과 급여, 커미션 및 소속부서명을 조회하기
SELECT E.FIRST_NAME, E.SALARY, E.COMMISSION_PCT, D.DEPARTMENT_ID
FROM EMPLOYEES E, DEPARTMENTS D
WHERE E.COMMISSION_PCT IS NOT NULL
AND E.DEPARTMENT_ID = D.DEPARTMENT_ID(+);
 
-- 커미션을 받는 직원들의 이름과 급여, 커미션 및 소속부서명과 직종, 직종제목을 조회하기
SELECT E.FIRST_NAME
, E.SALARY
, E.COMMISSION_PCT
, D.DEPARTMENT_ID
, J.JOB_ID
, J.JOB_TITLE
FROM EMPLOYEES E
, DEPARTMENTS D
, JOBS J
WHERE E.COMMISSION_PCT IS NOT NULL
AND E.DEPARTMENT_ID = D.DEPARTMENT_ID(+)
AND J.JOB_ID = E.JOB_ID;
 
-- 커미션을 받는 직원들의 이름과 급여, 커미션 및 그 직원의 매니저의 이름을 조회하기
SELECT 직원.FIRST_NAME
, 직원.SALARY
, 직원.COMMISSION_PCT
, 매니저.FIRST_NAME
FROM EMPLOYEES 직원, EMPLOYEES 매니저
WHERE 직원.COMMISSION_PCT IS NOT NULL
AND 직원.MANAGER_ID = 매니저.EMPLOYEE_ID;
 
-- 커미션을 받는 직원들의 이름과 급여, 커미션, 소속부서명 및 그 직원의 매니저의 이름과 매니저의 
-- 소속부서명을 조회하기
SELECT 직원.FIRST_NAME
, 직원.SALARY
, 직원.SALARY
, 직원_부서.DEPARTMENT_NAME
, 매니저.FIRST_NAME
, 매니저_부서.DEPARTMENT_NAME
FROM EMPLOYEES 직원, EMPLOYEES 매니저, DEPARTMENTS 직원_부서, DEPARTMENTS 매니저_부서
WHERE 직원.MANAGER_ID = 매니저.EMPLOYEE_ID
AND 매니저_부서.DEPARTMENT_ID = 매니저.DEPARTMENT_ID
AND 직원_부서.DEPARTMENT_ID = 직원.DEPARTMENT_ID
AND 직원.COMMISSION_PCT IS NOT NULL;
 
-- 급여등급이 A등급인 직원 수를 조회하기
SELECT COUNT(*)
FROM EMPLOYEES E, JOB_GRADES J
WHERE J.LOWEST_SALARY <= E.SALARY
AND J.HIGHEST_SALARY >= E.SALARY
AND J.GRA = 'A';
 
-- 급여등급이 E등급인 상사에게 보고하는 직원의 이름과 급여를 조회하기
SELECT 직원.FIRST_NAME, 직원.SALARY
FROM EMPLOYEES 직원, EMPLOYEES 상사, JOB_GRADES 상사_등급
WHERE 상사_등급.LOWEST_SALARY <= 상사.SALARY
AND 상사_등급.HIGHEST_SALARY >= 상사.SALARY
AND 직원.MANAGER_ID = 상사.EMPLOYEE_ID
AND 상사_등급.GRA = 'E';
 
-- 급여등급이 E등급인 상사에게 보고하는 직원의 이름, 급여, 소속부서명을 조회하기
SELECT 직원.FIRST_NAME, 직원.SALARY, 직원_부서.DEPARTMENT_NAME
FROM EMPLOYEES 직원, EMPLOYEES 상사, JOB_GRADES 상사_등급, DEPARTMENTS 직원_부서
WHERE 직원.MANAGER_ID = 상사.EMPLOYEE_ID
AND 상사_등급.LOWEST_SALARY <= 상사.SALARY
AND 상사_등급.HIGHEST_SALARY >= 상사.SALARY
AND 직원.DEPARTMENT_ID = 직원_부서.DEPARTMENT_ID
AND 상사_등급.GRA = 'E';
 
-- 급여등급이 E등급인 상사에게 보고하는 직원의 이름, 급여, 그 직원의 급여등급을 조회하기
SELECT 직원.FIRST_NAME, 직원.SALARY, 직원_등급.GRA
FROM EMPLOYEES 직원, EMPLOYEES 상사, JOB_GRADES 상사_등급, JOB_GRADES 직원_등급
WHERE 직원.MANAGER_ID = 상사.EMPLOYEE_ID
AND 상사_등급.LOWEST_SALARY <= 상사.SALARY
AND 상사_등급.HIGHEST_SALARY >= 상사.SALARY
AND 직원_등급.LOWEST_SALARY <= 직원.SALARY
AND 직원_등급.HIGHEST_SALARY >= 직원.SALARY
AND 상사_등급.GRA = 'E';
 
-- 급여등급에 따라서 인상된 급여를 조회하기
-- 직원이름, 급여, 급여등급, 인상된 급여
-- 인상률: A등급 1%, B등급:3%, C등급: 5%, D등급: 7%, E등급: 10%, F등급 15% 인상시킨다.
SELECT E.FIRST_NAME, E.SALARY, JG.GRA, 
CASE WHEN JG.GRA = 'A' THEN TRUNC(1.01*E.SALARY)
        WHEN JG.GRA = 'B' THEN TRUNC(1.03*E.SALARY)
        WHEN JG.GRA = 'C' THEN TRUNC(1.05*E.SALARY)
        WHEN JG.GRA = 'D' THEN TRUNC(1.07*E.SALARY)
        WHEN JG.GRA = 'E' THEN TRUNC(1.10*E.SALARY)
        WHEN JG.GRA = 'F' THEN TRUNC(1.15*E.SALARY)
        END AS 급여인상분
FROM EMPLOYEES E, JOB_GRADES JG
WHERE E.SALARY >= JG.LOWEST_SALARY
AND E.SALARY <= JG.HIGHEST_SALARY;
 
-- DECODE(JG.GRA, 'A' TRUNC(~)도 가능
 
-- 사원의 아이디, 사원이름, 급여, 급여등급, 직종아이디, 직종제목, 
-- 소속부서 아이디, 부서명, 소재지주소, 소재지의 국가를 조회하기(6개 조인)
SELECT E.EMPLOYEE_ID, E.FIRST_NAME, E.SALARY, JG.GRA, E.JOB_ID, J.JOB_TITLE, E.DEPARTMENT_ID, D.DEPARTMENT_NAME, L.CITY, C.COUNTRY_ID
FROM EMPLOYEES E, DEPARTMENTS D, JOB_GRADES JG, JOBS J, LOCATIONS L, COUNTRIES C
WHERE E.SALARY >= JG.LOWEST_SALARY
AND E.SALARY <= JG.HIGHEST_SALARY
AND E.DEPARTMENT_ID = D.DEPARTMENT_ID(+)
AND E.JOB_ID = J.JOB_ID
AND L.LOCATION_ID(+= D.LOCATION_ID
AND L.COUNTRY_ID = C.COUNTRY_ID(+);
cs

'Oracle Database SQL' 카테고리의 다른 글

190408  (0) 2019.06.07
190405  (0) 2019.06.07
190403  (0) 2019.06.07
190402  (0) 2019.06.07
090401  (0) 2019.06.07

+ Recent posts