SUBQUERY 에 대해 학습하였다



서브쿼리 안의 내용(전 직원의 평균급여를 계산)의 조회 결과가 하나이기 때문에 일반 연산자를 사용하여 EMPLOYEE 테이블에서 평균 급여보다 높은 급여인 직원의 정보 조회
서브쿼리 SELECT 절에 나열된 컬럼 수가 여러개 일 때
EX) 퇴사한 여직원과 같은 부서, 같은 직급에 해당하는 사원의 이름, 직급, 부서, 입사일을 조회
: 조건이 두 개임(같은 부서,같은 직급)
SELECT EMP_NAME, JOB_CODE, DEPT_CODE,HIRE_DATE
FROM EMPLOYEE e
WHERE (DEPT_CODE,JOB_CODE) = ( SELECT DEPT_CODE, JOB_CODE
FROM EMPLOYEE e
WHERE ENT_YN = 'Y'
AND SUBSTR(EMP_NO,8,1) = '2');
WHERE 문에 조건을 두 개 넣고(괄호 필수) 서브쿼리에서 조회된 값이 WHERE의 순서에 맞게 설정함

서브쿼리 안의 내용(부서별 최고 급여를 받는)의 결과가 그림처럼 다수의 행으로 표현됨
-> 단순 연산이나 비교 불가 따라서 IN 사용
해석: EMPLOYEE 테이블에서 DEPT_CODE 별로 묶은다음 DEPT_CODE 별 최고 급여를 조회(서브쿼리)
EMPLOYEE 테이블에서 급여가 서브쿼리 결과 목록 안에 있으면(즉, 부서별 최고 급여에 해당하면)
직원 정보를 조회한다
서브쿼리 조회 결과 행 수와 열 수가 여러개 일 때 : 비교 연산 불가 -> IN 사용
EX) 직급별 나이가 가장 어린 직원의 사번, 이름, 직급명, 나이, 보너스 포함 연봉을 조회하고
나이순으로 내림차순 정렬하세요
풀이: SELECT EMP_ID,EMP_NAME,JOB_NAME,123-SUBSTR(EMP_NO,1,2) 나이,(SALARY + NVL(SALARYBONUS,0))12||'원' 보너스포함연봉
FROM EMPLOYEE e
JOIN JOB j USING(JOB_CODE)
WHERE (JOB_CODE,123-SUBSTR(EMP_NO,1,2)) IN(SELECT JOB_CODE, MIN(123-SUBSTR(EMP_NO,1,2) ) 최소나이
FROM EMPLOYEE e
GROUP BY JOB_CODE)
ORDER BY 나이 DESC;

상관쿼리는 먼저 메인쿼리 한 행을 조회하고
해당 행이 서브쿼리의 조건을 충족하는지 확인하여 SELECT를 진행함
해석 순서가 기존 서브쿼리와 다르게
메인쿼리 1행 -> 1행에 대한 서브쿼리 -> 메인으로 리턴
메인쿼리 2행 -> 2행에 대한 서브쿼리 .......
메인쿼리의 행의 수 만큼 서브쿼리가 생성되어 진행됨
EX) 직급별 급여 평균보다 급여를 많이 받는 직원의 이름, 직급코드, 급여 조회
SELECT EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE MAIN -- MAIN 쿼리
WHERE SALARY > (SELECT AVG(SALARY) -- SUB 쿼리
FROM EMPLOYEE SUB
WHERE SUB.JOB_CODE = MAIN.JOB_CODE);
메인 쿼리: 23행중 1행의 데이터(선동일) 가져와서 서브쿼리로 이동
서브 쿼리: 메인쿼리의 JOB_CODE를 가지고 WHERE문 실행
(J1 의 평균 급여 조회) 한 뒤 결과값(800만원)을 가지고
메인쿼리로 이동 후 메인쿼리의 WHERE문과 비교
이걸 메인쿼리의 행의 개수만큼 반복

메인쿼리에서의 조회 결과중 1행을 가지고 서브쿼리로 이동(선동일) 서브쿼리에서는 선동일의
MANAGER_ID 와 같은 EMP_ID가 있는지 조건절을 수행하고 있으면 해당 직원의 이름을 반환하고
없으면 '없음'을 반환(메인으로 리턴) 이후 메인에서 SELECT 절을 수행하고 다시 2행인 송종기를 가지고 서브쿼리로 이동 -> 조건절을 수행(송종기의 MANAGER_ID와 같은 EMP_ID인 선동일 리턴)
....

좋은 글 감사합니다. 자주 올게요 :)