✿∘˚˳°∘°

20일차 : GROUP BY / JOIN 본문

국비수업/DB

20일차 : GROUP BY / JOIN

_HYE_ 2022. 12. 23. 13:42

2022/12/23

 

[ 1. GROUP BY & HABING ] ========================================================

그룹함수는 일반컬럼과 사용불가(출력되는 ROW의 수가 다르기 때문에), GROUP BY 그룹의 기준을 정해주는 분법

SELECT SALARY FROM EMPLOYEE;
SELECT SUM(SALARY) FROM EMPLOYEE; 
-- 조회되는 모든 ROW가 하나의 그룹(조회되는 행이 하나의 그룹으로 묶이는것)
-- 23명 전체의 급여합계
SELECT SALARY FROM EMPLOYEE WHERE DEPT_CODE='D9';
SELECT SUM(SALARY) FROM EMPLOYEE WHERE DEPT_CODE='D9';

SELECT DEPT_CODE, SUM(SALARY) 
FROM EMPLOYEE 
GROUP BY DEPT_CODE;
-- 한부서에대한 SUM은 볼수있지만 여러부서는 불가능(WHERE절을 여러개 쓸 수 없으니까)
-- DEPT_CODE가 동일한 ROW를 하나의 그룹으로잡음 D1이 하나의그룹 D2가 하나의그룹

-- GROUP BY 컬럼이 아니라 값을 넣어도 사용가능!
SELECT 
    DECODE(SUBSTR(EMP_NO,8,1), '1','남','2','여') 성별, 
    COUNT(*) 인원수,
    SUM(SALARY) 급여합계,
    FLOOR(AVG(SALARY)) 급여평균
FROM EMPLOYEE
GROUP BY DECODE(SUBSTR(EMP_NO,8,1), '1','남','2','여');
-- 성별로 그룹을 나눌 수 있다.

/*          동작순서
    SELECT     5 
    FROM       1
    WHERE      2  
    GROUP BY   3
    HAVING     4
    ORDER BY   6
*/

-- 그룹별평균을 구한 후 평균급여가 300만원 이상인 부서만 출력
SELECT DEPT_CODE, FLOOR(AVG(SALARY)) 평균급여
FROM EMPLOYEE
WHERE SALARY >= 3000000
GROUP BY DEPT_CODE
ORDER BY 2 DESC;
-- WHERE절의 동작순서가 2번째이기 때문에 우선 급여가 300이상인 사람을 뽑고 
-- GROUP BY / SELECT 실행
-- 이럴때 사용하는게 HAVING
-- HAVING : GROUP BY결과로 나온 데이터에 조건을 부여하는 경우 사용
-- 조건을 WHERE에 걸지 HAVING에 걸지 생각해야함
SELECT DEPT_CODE, FLOOR(AVG(SALARY)) 평균급여
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING FLOOR(AVG(SALARY)) >= 3000000
ORDER BY 2 DESC;
-- 통계를 낼 때 좋은문법 : ROLLUP, CUBE

 

[ 2. JOIN ] ======================================================================== 

SELECT * FROM USER_TABLES;
-- 현재 생성되어있는 테이블종류확인가능(메인은 EMPLOYEE테이블)
SELECT * FROM EMPLOYEE; -- 사원정보
SELECT * FROM DEPARTMENT; -- 부서정보
SELECT * FROM JOB; -- 직급
SELECT * FROM LOCATION; -- 지역(영문)
SELECT * FROM NATIONAL; -- 지역(한글)
SELECT * FROM SAL_GRADE; -- 급여등급
-- DEPARTMENT에서 LOCATION_ID를 통해 LOCATION정보를 확인
-- 바로바로 조회가안되고, 다 확인을 해줘야함

-- JOIN : 한 개 이상의 테이블에서 데이터를 조회하기 위해 사용, 
-- 수행결과는 하나의 RESULT SET으로 나온다 

-- EMPLOYEE 테이블, DEPARTMENT 테이블 JOIN
-- 둘 사이에 데이터를 연결해주는 컬럼 찾기(데이터가 같은 컬럼)
-- EMPLOYEE : DEPT_CODE / DEPARTMENT : DEPT_ID
-- 1. ORACLE 전용문법
    SELECT EMP_NAME, DEPT_CODE, DEPT_TITLE
    FROM EMPLYOEE, DEPARTMENT
    WHERE DEPT_CODE = DEPT_ID;
-- EMPLOYEE테이블에는 DEPT_TITLE 컬럼이 없기때문에 에러
-- 추가로 조회해줄 테이블을 FROM에서 테이블명1,테이블명2 
-- 그리고 WHERE에서 데이터를 연결해주는 컬럼조건을 넣어준다
-- 부서가없는직원(DEPT_CODE = NULL)인 직원은 조건이 맞지않으므로 조회결과에서 제외
-- 2. ANSI 표준구문(대부분의 DB에서 사용가능)
    SELECT EMP_NAME, DEPT_CODE, DEPT_TITLE
    FROM EMPLOYEE 
    JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
-- JOIN 테이블명 ON (조건)
    
-- EMPLOYEE테이블 - JOB테이블 JOIN
-- 둘 사이에 데이터를 연결 해주는 컬럼
-- EMPLOYEE : JOB_CODE, JOB : JOB_CODE
-- 1. ORACLE 전용 문법
    SELECT EMP_NAME, E.JOB_CODE, JOB_NAME
    FROM EMPLOYEE E, JOB J
    WHERE E.JOB_CODE = J.JOB_CODE;
-- 비교해야할 컬럼명이 같음 : JOB_CODE에서 에러발생(JOB_CODE의 소속을 알 수 없음)
-- 테이블명.컬럼명으로 구분을해준다
-- 테이블명 별명 으로도 가능!
-- 2. ANSI 표준구문 방법1
    SELECT EMP_NAME, E.JOB_CODE, JOB_NAME
    FROM EMPLOYEE E
    JOIN JOB J ON (E.JOB_CODE = J.JOB_CODE);
-- 3. ANSI 표준구문 방법2 : 비교해야할 컬럼명이 동일한 경우엔 문법이 하나 더 있다
    SELECT EMP_NAME, JOB_CODE, JOB_NAME
    FROM EMPLOYEE
    JOIN JOB USING(JOB_CODE);
-- USING을 사용하면 컬럼을 구분하지않아도 됨
-- ON 과 USING의 차이점 
-- USING(컬럼) 컬럼명이 동일하다는걸 알려주는것 - 같은거니까 그냥 써~
-- JOIN을 할때에는 내가 비교해야할 컬럼명이 같은지 다른지 꼭 확인해보기

 

JOIN의 종류 : INNER JOIN / OUTER JOIN / CROSS JOIN / SELF JOIN

 

2 - 1 )  INNER JOIN

-- INNER JOIN : JOIN조건(DEPT_CODE = DEPT_ID)에 일치하는 데이터만 출력 
--              그래서 DEPT_CODE가 NULL인직원은 조회결과제외
--              명시하지않아도 됨(명시하지않으면 기본적으로 INNER JOIN)
SELECT EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);

 

2 - 2 ) OUTER JOIN

-- OUTER JOIN : JOIN조건에 일치하지 않더라도 JOIN결과에 포함
--              LEFT JOIN / RIGHT JOIN / FULL JOIN
--              일치하지않는 결과가 어느테이블에 있을지 모르므로 나뉜다
-- 1) LEFT JOIN
-- JOIN문 기준으로 왼쪽에 있는 테이블(현재EMPLOYEE)은 조건에 일치하지 않더라도 조인결과에 포함
-- EMP_NAME : 이오리, 하동운은 DEPT_CODE가 없지만 조회가능 
-- 단, 데이터는 없으므로 NULL로 출력
SELECT EMP_NAME, DEPT_CODE, DEPT_TITLE 
FROM EMPLOYEE LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
-- 2) RIGHT JOIN
-- 해외영업3부(D7), 마케팅(D3), 국내영업(D4) 에 해당하는 직원은 없지만 부서는 존재
-- 오른쪽에 있는 데이터는 조건에 상관없이 모두 출력되기 때문에 조회가된다(데이터 NULL)
SELECT EMP_NAME, DEPT_CODE, DEPT_TITLE 
FROM EMPLOYEE RIGHT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
-- 3) FULL JOIN
SELECT EMP_NAME, DEPT_CODE, DEPT_TITLE 
FROM EMPLOYEE FULL JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
-- LEFT JOIN 결과와 RIGHT JOIN 결과 모두 출력(부서가 없는직원 직원이없는부서 모두출력)

 

2 - 3 ) CROSS JOIN

-- CROSS JOIN : 조인되는 테이블의 각 행들이 모두 매핑
--              EMPLOYEE 테이블과 DEPARTMENT테이블을 조인시킬때 
--              사원한명당 DEPARTMENT결과 전체로 출력되는 것
SELECT EMP_NAME, DEPT_CODE, DEPT_TITLE 
FROM EMPLOYEE CROSS JOIN DEPARTMENT ORDER BY 1;
-- CROSS조인은 일치하는 데이터뿐만 아니라 모든 데이터를 매치시키기 때문에 조건이 필요없다.
-- 결과 207개 : EMPLOYEE ROW(23) DEPARTMENT ROW(9) -> 23*9 = 207
-- 23명이 한명당 아홉개가 매핑되어 출력

 

2 - 4 ) SELF JOIN

-- SELF JOIN : 동일한 테이블을 JOIN
-- 언제써야하나? MANAGER_ID 상사의사번 - 옆에 상사이름을 출력하고싶을 때 셀프조인
--            EMPLOYEE테이블에서 값을 또 따와서 쓰고싶을 때 
-- 하나는 사번테이블 / 하나는 매니저테이블이라고 생각하고 사용
SELECT EMP.EMP_ID, EMP.EMP_NAME, EMP.MANAGER_ID, MAN.EMP_NAME 
FROM EMPLOYEE EMP
JOIN EMPLOYEE MAN ON(EMP.MANAGER_ID = MAN.EMP_ID);
-- 조건 사원테이블의 매니저아이디와 매니저테이블의 사원아이디가 동일하도록 조건을 걸어줌
-- 단, 같은테이블을 조인해서 모든 컬럼명이 겹치지때문에, 컬럼의 소속을 모두 구분해줘야 한다.
-- 생긴게 똑같을 뿐 둘을 별도의 테이블이라고 생각하는게 쉽다.

 

2 - 5 ) 다중조인

-- 다중조인
SELECT * FROM EMPLOYEE;
SELECT * FROM DEPARTMENT;
SELECT * FROM LOCATION;
-- 조인을 여러개 해야할 때가있음 : A사원이 어디에서 일하는지 알고싶음
-- LOCATION테이블은 EMPLOYEE와 접점이 하나도없음 - DEPARTMENT를 거쳐야함

SELECT EMP_NAME, DEPT_CODE, DEPT_TITLE, NATIONAL_CODE
FROM EMPLOYEE 
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID) 
LEFT JOIN LOCATION ON(LOCATION_ID = LOCAL_CODE);
-- 다중조인의 경우 JOIN순서를 고려해줘야함(바뀌면안됨) 
-- 먼저 EMPLOYEE랑 DEPARTMENT가 JOIN되고 그 결과가 LOCATION이랑 JOIN
-- OUTJOIN을 할 경우(전부출력할경우) LEFT/RIGTH JOIN을 모두 해줘야함

/*          동작순서
    SELECT     6 
    FROM       1
    JOIN       2
    WHERE      3  
    GROUP BY   4
    HAVING     5
    ORDER BY   7
*/

 

 ▶ JOIN 연습문제

-- 문제1. 1970년대생 / 성별 여 / 성 전 - 사원명, 주민번호, 부서명, 직급명
-- 이름/주번 - EMPLOYEE, 부서 - DEPARTMENT, 직급 - JOB
SELECT EMP_NAME 사원명, EMP_NO 주민번호, DEPT_TITLE 부서명, JOB_NAME 직급명
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
JOIN JOB USING(JOB_CODE)
WHERE 
    EMP_NO LIKE '7%-2%'
--    (SUBSTR(EMP_NO, 1, 2) BETWEEN 70 AND 79) AND
--    (SUBSTR(EMP_NO, 8, 1) = 2) 
AND
    (EMP_NAME LIKE '전%');

-- 문제2. 이름에 '형'자가 들어가는 직원들의 사번, 사원명, 부서명 조회
SELECT EMP_ID, EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
WHERE EMP_NAME LIKE '%형%';

SELECT EMP_NAME, DEPT_CODE FROM EMPLOYEE;

-- 문제3. 해외영업부에 근무하는 사원명, 직급명, 부서코드, 부서명
SELECT EMP_NAME 사원명, JOB_NAME 직급명, DEPT_CODE 부서코드, DEPT_TITLE 부서명 
FROM EMPLOYEE 
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
JOIN JOB ON(EMPLOYEE.JOB_CODE = JOB.JOB_CODE)
WHERE DEPT_TITLE LIKE '해외영업%';
-- WHERE DEPT_CODE IN ('D5', 'D6', 'D7'); 이렇게 조회하면 JOIN을 사용하는 의미X

-- 문제4. 보너스포인트를 받는 직원 / 사원명, 보너스포인트, 부서명, 근무지역명
SELECT EMP_NAME, BONUS, DEPT_TITLE, LOCAL_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
LEFT JOIN LOCATION ON(LOCATION_ID = LOCAL_CODE)
WHERE BONUS IS NOT NULL;
-- DEPT_CODE가 NULL 인 값이 없음 : 조인할 때 조건에 막혀서 NULL인 사원 출력이안됨
-- 이경우 사용해주는게 LEFT / RIGHT
-- LOCATION_ID도 NULL임 : 출력시 조건에 막혀서 출력이안됨 - 또LEFT를 해줘야한다

-- 문제5. 부서코드 D2 / 사원명, 직급명, 부서명, 근무지역명
SELECT EMP_NAME, JOB_NAME, DEPT_TITLE, LOCAL_NAME
FROM EMPLOYEE
JOIN JOB USING(JOB_CODE)
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
JOIN LOCATION ON(LOCATION_ID = LOCAL_CODE)
WHERE DEPT_CODE = 'D2';
-- 조인순서를 고려해줘야한다 : JOB이 LOCATION보다 아래에와도 되지만 
-- DEPARTMENT는 LOCATION보다 위에있어야함

-- 문제6. 한국(KO)과 일본(JP)에 근무하는 직원들 / 사원명, 부서명, 지역명, 국가명 조회
SELECT EMP_NAME 사원명, DEPT_TITLE 부서명, LOCAL_NAME 지역명, NATIONAL_NAME 국가명
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
JOIN LOCATION ON(LOCATION_ID = LOCAL_CODE)
JOIN NATIONAL USING(NATIONAL_CODE)
WHERE NATIONAL_NAME IN('한국', '일본');

-- 문제7. 같은부서에 근무하는 직원들 / 사원명, 부서명, 동료이름(SELF JOIN)
-- 내정보가 들어있는 사원테이블 E | 동료들의 정보가 들어있는 사원테이블 P
-- 생긴것도 똑같고, 안의 데이터도 똑같지만 서로 다른테이블
SELECT E.EMP_NAME 사원명, DEPT_TITLE 부서명, P.EMP_NAME 동료이름
FROM EMPLOYEE E
JOIN EMPLOYEE P ON(E.DEPT_CODE = P.DEPT_CODE)
JOIN DEPARTMENT ON (E.DEPT_CODE = DEPT_ID)
WHERE E.EMP_NAME != P.EMP_NAME
ORDER BY 1;

-- 문제8. 보너스포인트가 없는 직원들 중에서 직급이 차장/사원인 직원들
--       사원명, 직급명, 급여 
SELECT EMP_NAME 사원명, JOB_NAME 직급명, SALARY 급여
FROM EMPLOYEE 
JOIN JOB USING(JOB_CODE)
WHERE BONUS IS NULL AND JOB_NAME IN ('차장', '사원');

 

[ 3. SET OPERATOR : 집합 연산자 ]  ====================================================

-- SET OPERATOR : 집합 연산자 
-- UNION / UNION ALL / INTERSECT / MINUS
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5';
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000;

-- 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;
-- 위(결과6개) 아래(결과8개) = 14개가 출력되어야하는데 12개만 출력되는이유 : 중복제거
-- UNION은 

-- UNION ALL : 조회결과를 합침(중복제거X, 정렬X)
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;

-- 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;

-- 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;

-- 게시판을 만든다고 가정했을때, 게시판1 게시판2 의 게시글을 통합검색할 때 UNION사용

 

[ 4. SUBQUERY ] ==================================================================

 

4 - 1 ) 단일행SUBQUERY

-- SUBQUERY : 하나의 SELECT문(메인쿼리) 안에 SELECT를 하나 더 넣어서 사용
-- 서브쿼리는 메인쿼리 실행 전 한번만 실행

-- 단일행 SUBQUERY 
-- 전직원의 평균급여보다 많은 급여를 받는 직원의 사번, 이름, 직급코드, 급여 출력
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > (전직원급여의 평균);
-- 현재 전직원의 평균급여를 모름 : 구하는 쿼리문은간단
SELECT AVG(SALARY) FROM EMPLOYEE;
-- WHERE에 서브쿼리를 넣어줌
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > (SELECT AVG(SALARY) FROM EMPLOYEE);

-- 전지연 직원의 관리자의 이름, 급여, 사번출력 - SUBQUERY
SELECT EMP_NAME, SALARY, EMP_ID
FROM EMPLOYEE
WHERE EMP_ID = (SELECT MANAGER_ID FROM EMPLOYEE WHERE EMP_NAME = '전지연');
-- 전지연 직원의 관리자의 이름, 급여, 사번출력 - JOIN
SELECT E1.EMP_NAME, E1.SALARY, E1.EMP_ID
FROM EMPLOYEE E1
JOIN EMPLOYEE E2 ON (E1.EMP_ID = E2.MANAGER_ID)
WHERE E2.EMP_NAME = '전지연';
-- JOIN보다 SUBQUERY를 사용하는게 가독성이 더 좋음, 서브쿼리는 조인대체가능

 

 ▶ 단일행 SUBQUERY 실습문제

-- 1. 윤은해와 급여가 같은 사원들을 검색해서 사번, 이름, 급여 출력(단, 윤은해 제외)
SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE 
     SALARY = (SELECT SALARY FROM EMPLOYEE WHERE EMP_NAME = '윤은해')
     AND
     EMP_NAME != '윤은해';

-- 2. EMPLOYEE테이블에서 기본급여가 가장많은사람과 가장적은사람의 사번, 사원명, 기본급여
SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY = (SELECT MAX(SALARY) FROM EMPLOYEE) OR
      SALARY = (SELECT MIN(SALARY) FROM EMPLOYEE);

-- 3. D1,D2부서에 근무하는 사원들 중 D5부서의 평균급여보다 급여가 많은 사람들의
--    부서코드, 사원번호, 이름, 급여
SELECT DEPT_CODE, EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE 
    DEPT_CODE IN('D1', 'D2') AND
    SALARY > (SELECT AVG(SALARY) FROM EMPLOYEE WHERE DEPT_CODE = 'D5');

 

4 - 2 ) 다중행 SUBQUERY

-- 다중행서브쿼리(조회결과가 N행1열)
-- 송종기, 박나라가 속한 부서에 속한 사원들의 사번, 이름, 부서, 급여 출력
-- 방법 1.단일행버전 
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE 
    DEPT_CODE = (SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME='송종기')
    OR
    DEPT_CODE = (SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME='박나라');
-- 방법 2.단일행버전 IN
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE 
    DEPT_CODE IN (
        (SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME='송종기'),
        (SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME='박나라')
    );
    
-- 방법3. 다중행버전
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE 
    DEPT_CODE IN (
     SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME IN ('송종기', '박나라')
    );
-- 다중행 서브쿼리는 리턴값이 두개가 되므로 DEPT_CODE = (쿼리문) 이되면 에러발생 / IN사용
-- 단일행으로도 같은결과를 낼 수 있지만, 조금더 귀찬

 

4 - 3 ) 다중열 SUBQUERY

-- 다중열 서브쿼리 : 서브쿼리 수행결과가 1행 N열 
-- 퇴사한직원과 같은부서, 같은직급에 해당하는 직원의 이름, 부서, 직급 
-- 단일행버전
SELECT EMP_NAME, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
WHERE 
    DEPT_CODE = (SELECT DEPT_CODE FROM EMPLOYEE WHERE ENT_YN = 'Y')
    AND
    JOB_CODE = (SELECT JOB_CODE FROM EMPLOYEE WHERE ENT_YN = 'Y');
-- 다중열버전
SELECT EMP_NAME, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
WHERE 
    (DEPT_CODE, JOB_CODE) 
    IN(
        (SELECT DEPT_CODE, JOB_CODE FROM EMPLOYEE WHERE ENT_YN = 'Y')
      );

 

[ 4. 기타연산자 ] ==================================================================

 

4 - 1 ) ANY

-- ANY(값1, 값2...,값) 연산자 : 여러값중에 하나라도 TRUE면 TRUE
SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY > ANY(2000000, 3000000, 4000000);
-- 비교대상 > ANY() : 최소값보다 크면
-- ANY를 사용하지않을 때 코드 
-- WHERE SALARY > 2000000 OR SALARY > 3000000 OR SALARY > 4000000
-- 2000000, 3000000의 경우는 의미가없다(400만보다 크면 앞의 두개는 만족하므로)
SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY < ANY(2000000, 3000000, 4000000);
-- 비교대상 < ANY() : 최대값보다 작으면
-- ANY를 사용하지않을 때 코드 
-- WHERE SALARY < 2000000 OR SALARY < 3000000 OR SALARY < 4000000

 

4 - 2 ) ALL

-- ALL(값1, 값2...,값) 연산자 : 여러값이 모두 TRUE면 TRUE
SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY > ALL(2000000, 3000000, 4000000);
-- ALL를 사용하지않을 때 코드 
-- WHERE SALARY > 2000000 AND SALARY > 3000000 AND SALARY > 4000000
-- 비교대상 >  ALL() : 최대값보다 크면
SELECT EMP_ID, EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY < ALL(2000000, 3000000, 4000000);
-- ALL를 사용하지않을 때 코드 
-- WHERE SALARY < 2000000 AND SALARY < 3000000 AND SALARY < 4000000
-- 비교대상 <  ALL() : 최소값보다 작으면

 

 

 

[ 후기 ] -------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

오늘 실수한 점

없음!

'국비수업 > DB' 카테고리의 다른 글

23일차 : PL/SQL  (0) 2022.12.28
22일차 : ALTER, DROP / TCL / OBJECT  (0) 2022.12.27
21일차 : 서브쿼리 / DML / DDL  (0) 2022.12.26
19일차 : 함수  (0) 2022.12.22
18일차 : SELECT, 연산자  (0) 2022.12.21
Comments