: 데이터베이스의 SubQuery에 대한 이해
- 메인 쿼리 내부에 정의된 쿼리
- 다른 SELECT 문의 내부에 정의된 SELECT문
- 서브쿼리를 포함시킬 수 있는 곳 : WHERE절 / HAVING절 / FROM절 =인라인뷰
- 형식)
SELECT COLUMN, COLUMN
FROM TABLE
WHERE COLUMN 연산자 (SELECT COLUMN
FROM TABLE)
- 실행결과로 한 행만 반환하는 서브쿼리 (1행1열 데이터 반환)
-- 101번 사원에게 보고받는 상사와 같은 상사에게 보고하는 직원의 아이디, 이름 조회하기
SELECT EMPLOYEE_ID, FIRST_NAME
FROM EMPLOYEES
WHERE MANAGER_ID = (SELECT MANAGER_ID
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 101);
- 실행 결과로 여러 행을 반환하는 서브쿼리 (N행1열 데이터 반환)
-- 'Steven'과 같은 해에 입사한 직원의 아이디, 이름, 입사일 조회하기
SELECT EMPLOYEE_ID, FIRST_NAME, HIRE_DATE
FROM EMPLOYEES
WHERE TO_CHAR(HIRE_DATE, 'YYYY') IN (SELECT TO_CHAR(HIRE_DATE, 'YYYY')
FROM EMPLOYEES
WHERE FIRST_NAME = 'Steven');
* 단일행 / 다중행 서브쿼리 연산자 비교
단일행 서브쿼리 | 다중행 서브쿼리 |
---|---|
= | IN |
<> | NOT IN |
> | >ANY, >ALL |
< | <ANY, <ALL |
- 두 개 이상의 컬럼값이 조회조건으로 반환되는 서브쿼리
-- 각 부서별 최저 급여를 받는 직원의 아이디, 이름, 급여, 부서아이디 조회하기
SELECT EMPLOYEE_ID, FIRST_NAME, SALARY, DEPARTMENT_ID
FROM EMPLOYEES
WHERE (DEPARTMENT_ID, SALARY) IN (SELECT DEPARTMENT_ID, MIN(SALARY)
FROM EMPLOYEES
WHERE DEPARTMENT_ID IS NOT NULL
GROUP BY DEPARTMENT_ID);
- GROUP BY 절을 사용해서 그룹화하고, 그룹함수를 실행한 결과를 필터링하는 HAVING 절에도 서브쿼리 사용이 가능함
SELECT COLUMN, 그룹함수
FROM TABLE1
GROUP BY COLUMN
HAVING 그룹함수 연산자 (SELECT COLUMN
FROM TABLE)
- 서브쿼리에서 메인쿼리의 컬럼을 참조하는 쿼리
-- 직원들 중에서 자신이 소속된 부서의 평균급여보다 급여를 많이 받는 사원의 아이디, 이름, 급여 조회하기
SELECT X.EMPLOYEE_ID, X.FIRST_NAME, X.SALARY
FROM EMPLOYEES X
WHERE X.SALARY > (SELECT AVG(Y.SALARY)
FROM EMPLOYEES Y
WHERE Y.DEPARTMENT_ID = X.DEPARTMENT_ID);
* 일반서브쿼리와 상호연관서브쿼리의 차이점
1) 일반서브쿼리는 메인쿼리보다 먼저 실행됨
2) 일반서브쿼리는 딱 한번만 실행됨
3) 상호연관 서브쿼리는 메인쿼리문에서 처리되는 각 행에 대해서 한번씩 실행됨
- 하나의 행에서 하나의 값만 반환하는 서브쿼리
- SELECT절, INSERT문의 VALUES에서 사용
- DECODE, CASE의 조건 및 표현식에서 사용
-- 직원아이디, 직원이름 조회하기
SELECT X.EMPLOYEE_ID, X.FIRST_NAME,
(SELECT Y.FIRST_NAME
FROM EMPLOYEES Y
WHERE Y.EMPLOYEE_ID = X.MANAGER_ID)
FROM EMPLOYEES X;