- SQL에 포함되어 있는 또 다른 SQL
- 주로 단일 값 반환, 복잡한 필터링, 존재 여부 체크, 데이터 추출 등에서 사용
- 서브쿼리는 “()”(소활호)로 감싸서 사용
- 쿼리속도 저하가 발생할 가능성이 높으므로 주의해서 사용
- 웬만한 절은 서브쿼리가 사용 가능
WHERE 절에서 사용
- 단일 행 서브쿼리
서브쿼리가 단일 행 비교 연산자(=, <, <=, >, >=, <>)와 함께 사용할 떄는 서브쿼리의 결과 수가 반드시 1건 이하
2건 이상일 경우 오류 발생
-- D001 부서장의 사번과 이름 출력
SELECT
emp.emp_id
,emp.`name`
FROM employees emp
WHERE
emp.emp_id = (
SELECT depm.emp_id
FROM department_managers depm
WHERE
depm.dept_code = 'D001'
AND depm.end_at IS NULL
)
;

- 다중 행 서브쿼리
서브쿼리가 2건 이상 반환 될 경우에는 반드시 다중 행 비교연산자(IN, ALL, ANY, SOME, EXISTS등)을 사용한다.
-- 현제 부서장인 사원의 사번과 이름을 출력
SELECT
emp.emp_id
,emp.`name`
FROM employees emp
WHERE
emp.emp_id in (
SELECT depm.emp_id
FROM department_managers depm
WHERE
depm.end_at IS NULL
)
;

- 다중 열 서브쿼리
서브 쿼리의 결과가 복수의 컬럼을 반환할 경우, 메인 퀘리의 조건과 동시 비교
-- 현재 D002의 부서장이 해당 부서에 소속된 날짜 출력
SELECT
department_emps.*
FROM department_emps
WHERE
(department_emps.emp_id, department_emps.dept_code) IN (
select
department_managers.emp_id
,department_managers.dept_code
FROM department_managers
WHERE
department_managers.dept_code = 'D002'
AND department_managers.end_at IS NULL)
;

- 연관 서브쿼리
서브쿼리 내에서 메인쿼리의 컬럼이 사용된 서브쿼리
-- 부서장 직을 지냈던 경력이 있는 사원의 정보 출력
SELECT
employees.*
FROM employees
WHERE
employees.emp_id IN(
SELECT department_managers.emp_id
FROM department_managers
where
department_managers.emp_id = employees.emp_id
)
;

SELECT 절에서 사용
-- 사원별 역대 전체 급여 평균
SELECT
emp.emp_id
,(
SELECT AVG(sal.salary)
FROM salaries sal
WHERE emp.emp_id = sal.emp_id
) avg_sal
FROM employees emp
;

FROM 절에서 사용
SELECT
tmp.*
FROM (
SELECT
emp.emp_id
,emp.`name`
FROM employees emp
) tmp
;

INSERT문에서 사용
