--간단 서브쿼리 예시 1
--노옹철 사원과 같은 부서인 사원들
SELECT EMP_NAME
FROM EMPLOYEE
WHERE DEPT_CODE = (SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME='노옹철'); --D9
--간단 서브쿼리 예시 2
--전체 사원의 평균 급여보다 더 많은 급여를 받고 있는 사원들의 사번,이름,직급코드 조회
SELECT EMP_ID,EMP_NAME,JOB_CODE
FROM EMPLOYEE
WHERE SALARY>(SELECT FLOOR(AVG(SALARY)) FROM EMPLOYEE);
--직급이 대리이면서 ASIA 지역에 근무하는 직원들
--사번, 사원명, 직급명, 부서명, 근무지역명, 급여 조회
--오라클 전용 구문
SELECT E.EMP_ID 사번, E.EMP_NAME 사원명, J.JOB_NAME 직급명, D.DEPT_TITLE 부서명, N.NATIONAL_NAME 근무지역명, E.SALARY 급여
FROM EMPLOYEE E, JOB J, DEPARTMENT D, LOCATION L, NATIONAL N
WHERE E.JOB_CODE = J.JOB_CODE
AND E.DEPT_CODE = D.DEPT_ID
AND D.LOCATION_ID = L.LOCAL_CODE
AND L.NATIONAL_CODE = N.NATIONAL_CODE
AND J.JOB_NAME = '대리'
AND L.LOCAL_NAME LIKE 'ASIA%';
--ANSI 구문
SELECT E.EMP_ID 사번, E.EMP_NAME 사원명, J.JOB_NAME 직급명, D.DEPT_TITLE 부서명, N.NATIONAL_NAME 근무지역명, E.SALARY 급여
FROM EMPLOYEE E
LEFT JOIN JOB J ON(E.JOB_CODE=J.JOB_CODE)
LEFT JOIN DEPARTMENT D ON(E.DEPT_CODE=D.DEPT_ID)
LEFT JOIN LOCATION L ON(D.LOCATION_ID=L.LOCAL_CODE)
LEFT JOIN NATIONAL N ON(L.NATIONAL_CODE=N.NATIONAL_CODE)
WHERE J.JOB_NAME = '대리'
AND L.LOCAL_NAME LIKE 'ASIA%';
--70년대생이면서 여자이고, 성이 전씨인 직원들
--사원명, 주민번호, 부서명, 직급명 조회
--오라클 전용 구문
SELECT EMP_NAME 사원명, EMP_NO 주민번호, DEPT_TITLE 부서명, JOB_NAME 직급명
FROM EMPLOYEE E, DEPARTMENT D, JOB J
WHERE E.DEPT_CODE=D.DEPT_ID
AND E.JOB_CODE=J.JOB_CODE
AND SUBSTR(EMP_NO,1,2) LIKE '7%'
AND SUBSTR(EMP_NO,8,1) IN('2','4')
AND EMP_NAME LIKE '전%';
--ANSI 구문
SELECT EMP_NAME 사원명, EMP_NO 주민번호, DEPT_TITLE 부서명, JOB_NAME 직급명
FROM EMPLOYEE E
LEFT JOIN DEPARTMENT D ON(E.DEPT_CODE=D.DEPT_ID)
LEFT JOIN JOB J ON(E.JOB_CODE=J.JOB_CODE)
WHERE SUBSTR(EMP_NO,1,2) LIKE '7%'
AND SUBSTR(EMP_NO,8,1) IN('2','4')
AND EMP_NAME LIKE '전%';
--사번, 사원명, 직급명, 급여등급, 구분 조회
-- 이 때, 구분에 해당하는 값은
-- 급여등급이 S1, S2 인 경우 '고급'
-- 급여등급이 S3, S4 인 경우 '중급'
-- 급여등급이 S5, S6 인 경우 '초급' 으로 조회
--오라클 전용 구문
SELECT E.EMP_ID 사번, E.EMP_NAME 사원명, J.JOB_NAME 직급명, SAL_LEVEL 급여등급
,CASE WHEN SAL_LEVEL IN ('S1','S2') THEN '고급'
WHEN SAL_LEVEL IN ('S3','S4') THEN '중급'
WHEN SAL_LEVEL IN ('S5','S6') THEN '초급'
END 구분
FROM EMPLOYEE E, JOB J
WHERE E.JOB_CODE=J.JOB_CODE;
--오라클 국문
SELECT E.EMP_NAME,E.SALARY,S.SAL_LEVEL
FROM EMPLOYEE E, SAL_GRADE S
WHERE E.SALARY BETWEEN MIN_SAL AND MAX_SAL;
--ANSI
SELECT EMP_NAME,SALARY,S.SAL_LEVEL
FROM EMPLOYEE E
JOIN SAL_GRADE S ON (SALARY BETWEEN MIN_SAL AND MAX_SAL);
자체조인 (SELF JOIN)
같은 테이블끼리 조인하는 경우 사용하며 테이블 별칭 붙여서 서로 다른 테이블처럼 조인한다
--사원의 사번,사원명,사수의사번,사수명
--ORACLE 구문
SELECT E.EMP_ID 사번, E.EMP_NAME 직원명, M.MANAGER_ID 사수사번, M.EMP_NAME 사수명
FROM EMPLOYEE E, EMPLOYEE M
WHERE E.MANAGER_ID = M.EMP_ID(+); --LEFT OUTER JOIN
--ANSI 구문
SELECT E.EMP_ID 사번, E.EMP_NAME 사원명, E.MANAGER_ID 사수사번, M.EMP_NAME 사수명
FROM EMPLOYEE E
LEFT OUTER JOIN EMPLOYEE M ON (E.MANAGER_ID=M.EMP_ID);
--사원명,부서명의 모든 경우의 수를 출력
--오라클구문
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT; --23*9=207행 조회
--ANSI구문
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
CROSS JOIN DEPARTMENT;
--WHERE절에 기술하는 조인 조건이 잘못되었거나 아예 없을 경우 발생하는 구문
//ORACLE SELECT 컬럼명, ... FROM 테이블명1, 테이블명2, ... WHERE 기준컬럼=조인컬럼(+);
//ANSI SELECT 컬럼명, ... FROM 기준테이블명 LEFT OUTER JOIN 조인테이블명 ON (기준컬럼=조인컬럼);
--오라클 구문
SELECT EMP_NAME,SALARY,DEPT_TITLE
FROM EMPLOYEE,DEPARTMENT
WHERE DEPT_CODE=DEPT_ID(+);
--기준으로 삼지 않는 테이블의 컬럼명에 (+)를 붙여준다
--ANSI구문
SELECT EMP_NAME,SALARY,DEPT_TITLE
FROM EMPLOYEE
LEFT /*OUTER*/ JOIN DEPARTMENT ON (DEPT_CODE=DEPT_ID); --OUTER 생략가능
--EMPLOYEE테이블이 기준이 되었기 때문에 EMPLOYEE테이블에 존재하는 데이터는 모두 조회해옴
RIGHT OUTER JOIN
오른쪽에 기술한 테이블 기준으로 JOIN
//ORACLE SELECT 컬럼명, ... FROM 테이블명1, 테이블명2, ... WHERE 조인컬럼(+)=기준컬럼;
//ANSI SELECT 컬럼명, ... FROM 기준테이블명 RIGHT OUTER JOIN 조인테이블명 ON (기준컬럼=조인컬럼);
--ORACLE 구문
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+)=DEPT_ID;
--ANSI 구문
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE
RIGHT /*OUTER*/ JOIN DEPARTMENT ON (DEPT_CODE=DEPT_ID); --OUTER 생략가능
FULL OUTER JOIN
두 테이블이 가진 모든 행을 조회 (ANSI 구문 존재)
//ANSI SELECT 컬럼명, ... FROM 기준테이블명 FULL OUTER JOIN 조인테이블명 ON (기준컬럼=조인컬럼);
--ANSI 구문
SELECT EMP_NAME,SALARY,DEPT_TITLE
FROM EMPLOYEE
FULL /*OUTER*/ JOIN DEPARTMENT ON (DEPT_CODE=DEPT_ID); --OUTER 생략 가능
연결 시키고자 하는 컬럼의 값이 일치하는 행들만 조인되어 조회된다 (일치하지 않는 값들을 결과에서 제외)
동등비교연산자 = 사용 ("일치한다"라는 조건을 제시)
등가조인(EQUAL JOIN) - ORACLE
SELECT 조회할 컬럼명 나열 FROM 조회할 테이블명 나열 WHERE 연결할 컬럼에 대한 조건 제시("=")
--전체 사원들의 사번,사원명,부서코드,부서명 출력
--1)연결할 두 컬럼명이 다를 경우 EX)EMPLOYEE-'DEPT_CODE' / DEPARTMENT-'DEPT_ID'
SELECT EMP_ID,EMP_NAME,DEPT_CODE,DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE=DEPT_ID;
--부서코드가 일치하지 않는 값은 조회되지 않음(NULL, D3, D4, D7은 조회가 안됨 자료가 없기 때문!)
--2)연결할 두 컬럼명이 같을 경우 EX)EMPLOYEE-'JOB_CODE' / JOB-'JOB_CODE'
--방법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;
--조건제시
SELECT EMP_ID, EMP_NAME, BONUS
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID
AND DEPT_TITLE='인사관리부';
내부조인(INNER JOIN) - ANSI
//내부조인 (ANSI) : ON구문 SELECT 조회할 컬럼명 나열 FROM 기준 삼을 테이블명 1개 제시 JOIN 조인할 테이블명 1개 제시 ON (연결할 컬럼에 대한 조건 제시 ("="))
//내부조인(ANSI구문) : USING구문 SELECT 조회할 컬럼명 나열 FROM 기준 삼을 테이블명 1개 제시 JOIN 조인할 테이블명 1개 제시 USING (연결할 컬럼명 1개 제시)
--전체사원들의 사번,사원명,직급코드,직급명 조회
--연결할 두 컬럼이 같을 경우 EX)EMPLOYEE-'JOB_CODE' / JOB-'JOB_CODE'
--ON구문
SELECT EMP_ID,EMP_NAME,E.JOB_CODE,JOB_NAME
FROM EMPLOYEE E
/*INNER*/JOIN JOB J ON(E.JOB_CODE=J.JOB_CODE); --INNER 보통 생략
--USING구문(연결할 컬럼명이 같을경우만)
SELECT EMP_ID,EMP_NAME,JOB_CODE,JOB_NAME
FROM EMPLOYEE
JOIN JOB USING(JOB_CODE);--컬럼명이 동일하여 어떤 테이블 컬럼인지 명시하지 않아도 매칭
--cf.자연조인(NATURAL JOIN):등가조인 방법중 하나
--동일한 타입과 이름을 가진 컬럼을 조인 조건으로 이용하는 방법
SELECT EMP_ID,EMP_NAME,JOB_CODE,JOB_NAME
FROM EMPLOYEE
NATURAL JOIN JOB;
--두개의 테이블에 일치하는 컬럼이 단 한개만 존재할 경우 알아서 매칭
--조건제시
SELECT EMP_ID, EMP_NAME, BONUS
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE=DEPT_ID)
WHERE DEPT_TITLE='인사관리부';