[ 서브쿼리 (SUBQUERY) ]
다른 쿼리 내부에 포함되어 있는 SELECT문을 말한다.
서브쿼리는 괄호() 로 묶어서 표현한다.
서브쿼리 실행 후 메인쿼리를 실행한다.
서브쿼리는 단일 행 연산자(=, >=)와 다중 행 연산자(IN, NOT IN, ANY, EXISTS 등)들을 사용하여 표현한다.
메인쿼리와 서브쿼리
메인쿼리 = 부모쿼리 = 외부쿼리(outer query)
서브쿼리 = 자식쿼리 = 내부쿼리(inner query)
SELECT
FROM
WHERE 조건식 연산자 (SELECT FROM WHERE);
장점
1. 쿼리의 구조화를 통한 가독성 상승
2. 복잡한 JOIN, UNION과 같은 동작을 수행할 수 있는 또 다른 방법을 제공
서브쿼리를 사용 가능 한 곳
MySQL에서 서브쿼리를 포함할 수 있는 외부쿼리는 SELECT, INSERT, UPDATE, DELETE, SET, DO 문이 있다.
서브쿼리는 다른 서브쿼리 안에 포함될 수 있다.
-- 서브쿼리 안에 서브쿼리를 사용 가능하다.
SELECT A.ACTOR_ID, A.FIRST_NAME, A.LAST_NAME
FROM ACTOR A
WHERE A.ACTOR_ID IN (SELECT FA.ACTOR_ID
FROM FILM_ACTOR FA
WHERE FA.FILM_ID IN (SELECT F.FILM_ID
FROM FILM F
WHERE F.RATING IN ('G', 'PG', 'NC-17')));
위치에 따른 분류
SELECT column, (SELECT ...) -- 스칼라 서브쿼리(Scalar SubQuery): 하나의 컬럼처럼 사용 (표현 용도)
FROM (SELECT ...) -- 인라인 뷰(Inline View): 하나의 테이블처럼 사용 (테이블 대체 용도)
WHERE column = (SELECT ...) -- 중첩 서브쿼리(Nested SubQuery: 하나의 변수(상수)처럼 사용 (조건절)
중첩 서브쿼리
1. 단일 행 서브쿼리(Single Row SubQuery)
단 하나의 컬럼만 가지는 서브쿼리
-- SAKILA DB에서 카테고리가 COMEDY인 영화
SELECT FC.FILM_ID, F.TITLE
FROM FILM_CATEGORY FC, FILM F
WHERE FC.CATEGORY_ID = (SELECT C.CATEGORY_ID
FROM CATEGORY C
WHERE C.NAME='COMEDY')
AND FC.FILM_ID = F.FILM_ID;
2. 다중 행 서브쿼리(Multiple Row SubQuery)
다중 행 연산자(IN, NOT IN, ANY, EXISTS 등)들을 사용하여 표현하며, 여러 필드값을 반환한다.
-- MySQL의 world DB에서 영어, 스페인어, 한국어를 95%이상 사용하는 나라를 오름차순 조회
SELECT A.NAME
FROM COUNTRY A, COUNTRYLANGUAGE B
WHERE A.CODE = B.COUNTRYCODE
AND B.LANGUAGE IN ('KOREAN', 'SPANISH', 'ENGLISH')
AND B.PERCENTAGE>=95
ORDER BY A.NAME ASC;
3. 다중 컬럼 서브쿼리(Multiple Column SubQuery)
서브쿼리의 결과가 여러 컬럼의 데이터를 출력 해 주는 서브쿼리
-- Oracle 사원 DB에서 영업부서의 연봉, 부서번호, 사원번호를 출력
SELECT EMPNO, SAL, DEPTNO
FROM EMP
WHERE (SAL, DEPTNO) IN (SELECT SAL, DEPTNO
FROM EMP
WHERE DEPTNO=30
AND COMM IS NOT NULL);
인라인 뷰(Inline View)
FROM절에서 원하는 데이터를 조회하여 가상의 집합을 만들어 조인을 수행하거나 다시 조회할 때 사용한다.
무조건 별칭(Alias)을 생성하여야 한다.
-- Oracle 사원 DB에서
-- JOB이 매니저이면서, 20번 부서의 평균 급여보다 큰 다른 부서 사람들의
-- 부서번호, 사원명, 직급, 월급, 사원번호 조회
SELECT B.DEPTNO, B.ENAME, B.JOB, B.SAL, B.EMPNO
FROM (SELECT DEPTNO, ENAME, JOB, SAL, EMPNO
FROM EMP
WHERE SAL > (SELECT AVG(SAL)
FROM EMP
WHERE DEPTNO=20)) A, EMP B
WHERE A.EMPNO = B.EMPNO
AND B.MGR IS NOT NULL
AND B.DEPTNO != 20;
스칼라 서브쿼리(Scalar Subquery)
SELECT 문에 나타나는 서브쿼리로 다른 테이블에서 어떠한 값을 가져올 때 주로 쓰인다.
단 하나의 레코드만 조회가 가능하다.
일치하는 데이터가 없더라도 NULL값을 리턴할 수 있다.
-- Oracle 사원 DB에서 부서별 최대 급여정보 조회
SELECT DEPTNO, DNAME,
(SELECT MAX(SAL)
FROM EMP
WHERE DEPTNO = D.DEPTNO) SAL
FROM DEPT D;
참조
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!