Search
moon
sun

16.서브쿼리 ② (스칼라·인라인뷰·상관 서브쿼리)

•
SELECT절에 넣는 스칼라 서브쿼리를 쓰고, 조인과 상호 변환할 수 있다.
•
FROM절에 넣는 인라인 뷰를 임시 테이블처럼 사용할 수 있다.
•
상관 서브쿼리의 실행 방식을 이해하고 부서별 최고 급여자를 정확히 구할 수 있다.
•
EXISTS / NOT EXISTS 를 상관 서브쿼리로 완성할 수 있다.

1. 위치별 서브쿼리 — 오늘의 범위

위치/종류
명칭
반환
강의
WHERE
중첩 서브쿼리
조건용 값
15강
SELECT
스칼라 서브쿼리
1행 1컬럼
오늘
FROM
인라인 뷰
임시 테이블
오늘
(위치 무관)
상관 서브쿼리
메인 값을 참조
오늘

2. 스칼라 서브쿼리 ⭐⭐⭐

1) SELECT절에 값 하나를 가져온다

•
스칼라(Scalar) = 값 하나. 반드시 1행 1컬럼만 반환해야 한다.
•
컬럼처럼 SELECT 절에 놓여, 행마다 한 번씩 실행된다.
-- ============================================================ -- 【이해용 예제】 사원마다 자기 부서명을 붙이기 ★ -- ============================================================ SELECT E.ENAME AS 사원명, E.DEPTNO AS 부서번호, ( SELECT D.DNAME -- 스칼라 서브쿼리 (값 하나) FROM DEPT D WHERE D.DEPTNO = E.DEPTNO ) -- 바깥 E.DEPTNO 를 참조 (= 상관 서브쿼리) AS 부서명 FROM EMP E; -- 사원명 부서번호 부서명 -- ------ -------- ---------- -- SMITH 20 RESEARCH -- ALLEN 30 SALES -- CLARK 10 ACCOUNTING -- ... → 14건 -- -- ⭐ 각 사원 행마다 서브쿼리가 실행되어 그 사원의 부서명을 가져온다.
SQL
복사

2) 조인과 상호 변환 ⭐

-- ============================================================ -- 【시험용 예제】 같은 결과를 '조인' 과 '스칼라 서브쿼리' 두 가지로 ★★ -- ============================================================ -- 방법 ① 조인 (13강) SELECT E.ENAME, D.DNAME FROM EMP E, DEPT D WHERE E.DEPTNO = D.DEPTNO; -- 방법 ② 스칼라 서브쿼리 (같은 결과) SELECT E.ENAME, ( SELECT D.DNAME FROM DEPT D WHERE D.DEPTNO = E.DEPTNO ) AS DNAME FROM EMP E; -- → 두 방법 모두 사원명 + 부서명. 결과 동일.
SQL
복사

3) ⚠️ 매칭이 없으면 NULL — LEFT OUTER JOIN 효과 (14강 회수)

-- ============================================================ -- 【시험용 예제】 스칼라 서브쿼리가 못 찾으면 NULL 을 반환한다 ★★ -- 존재하지 않는 부서번호(99)를 가진 사원이 있다고 가정하면 -- ============================================================ SELECT E.ENAME, ( SELECT D.DNAME FROM DEPT D WHERE D.DEPTNO = E.DEPTNO ) AS 부서명 FROM EMP E; -- → 부서를 못 찾은 사원의 '부서명' 은 NULL 이 된다. -- -- ⭐ 이것은 INNER JOIN 처럼 '행이 사라지는' 게 아니라 -- LEFT OUTER JOIN 처럼 '사원은 남고 부서명만 NULL' 이 된다. (14강 회수) -- 스칼라 서브쿼리는 메인쿼리 행을 절대 줄이지 않는다.
SQL
복사

4) ⚠️ 반드시 1행 1컬럼

-- ❌ 여러 행을 반환하면 오류 SELECT E.ENAME, ( SELECT SAL FROM EMP WHERE DEPTNO = E.DEPTNO ) AS 급여 -- 부서에 여러 명! FROM EMP E; -- ORA-01427: single-row subquery returns more than one row -- → 스칼라 서브쿼리는 값 '하나' 만 반환해야 한다. 집계함수(MAX 등)로 1건을 만들거나 -- 조건을 좁혀 1건이 나오게 해야 한다.
SQL
복사

3. 인라인 뷰 ⭐⭐⭐

1) FROM절에 서브쿼리 = 임시 테이블

•
인라인 뷰(Inline View): FROM 절에 놓인 서브쿼리. 하나의 임시 테이블처럼 취급된다.
•
먼저 서브쿼리로 가공된 결과 집합을 만들고, 메인쿼리가 그것을 테이블처럼 조회한다.
-- ============================================================ -- 【이해용 예제】 부서별 평균급여를 먼저 구하고, 그걸 조회 ★ -- ============================================================ SELECT V.DEPTNO AS 부서번호, V.평균급여 FROM ( SELECT DEPTNO, ROUND(AVG(SAL)) AS 평균급여 -- 인라인뷰 안에서 집계 + 별칭 FROM EMP GROUP BY DEPTNO ) V -- 이 결과 집합에 V 라는 별칭 WHERE V.평균급여 >= 2000; -- 임시 테이블처럼 조건을 건다 -- 부서번호 평균급여 -- -------- -------- -- 10 2917 -- 20 2175 -- -- ⭐ 인라인뷰 안에서 만든 별칭(평균급여)을 바깥에서 컬럼처럼 쓸 수 있다. -- ⚠️ 계산식 컬럼(AVG(SAL))에는 반드시 별칭을 붙여야 바깥에서 참조할 수 있다.
SQL
복사

2) 인라인 뷰에서는 ORDER BY 가능 ⭐

-- ============================================================ -- 【시험용 예제】 WHERE 서브쿼리와 달리 인라인뷰는 ORDER BY 가능 ★★ -- ============================================================ SELECT ROWNUM AS 순위, V.ENAME, V.SAL FROM ( SELECT ENAME, SAL FROM EMP ORDER BY SAL DESC ) V -- 인라인뷰 안에서 정렬 (가능!) WHERE ROWNUM <= 3; -- 상위 3명 (Top-N 쿼리, 21강에서 자세히) -- 순위 ENAME SAL -- ---- ----- ----- -- 1 KING 5000 -- 2 SCOTT 3000 -- 3 FORD 3000 -- -- ⭐ 15강에서 "WHERE절 서브쿼리엔 ORDER BY 불가" 라고 했지만 -- 인라인뷰(FROM절)에서는 ORDER BY 를 쓸 수 있다. 이 차이가 시험에 나온다. -- ⭐ 이렇게 '정렬 후 상위 N개' 를 뽑는 것을 Top-N 쿼리라 한다 (21강).
SQL
복사
WHERE절 서브쿼리
인라인 뷰(FROM절)
ORDER BY
원칙적 불가
가능 ⭐
역할
조건용 값
임시 테이블

4. 상관 서브쿼리 ⭐⭐⭐

1) 메인쿼리의 값을 서브쿼리가 참조한다

•
상관(Correlated) 서브쿼리: 서브쿼리가 메인쿼리의 컬럼을 참조하는 것
•
메인쿼리 각 행마다 서브쿼리가 반복 실행된다

2) 부서별 최고 급여자 — 정확한 해결 ⭐⭐⭐

-- ============================================================ -- 【시험용 예제】 각 부서에서 가장 급여가 높은 사원 ★★★ -- 15강 IN 방식의 한계(다른 부서 최고급여와 겹치면 부정확)를 해결한다 -- ============================================================ SELECT ENAME, SAL, DEPTNO FROM EMP E WHERE SAL = ( SELECT MAX(SAL) FROM EMP WHERE DEPTNO = E.DEPTNO ); -- 바깥 E.DEPTNO 참조 = 상관! -- ENAME SAL DEPTNO -- ------ ----- ------ -- BLAKE 2850 30 -- SCOTT 3000 20 -- KING 5000 10 -- FORD 3000 20 → 4건 -- -- ⭐ 동작 방식 -- BLAKE(30번) 행 → 서브쿼리는 "30번 부서의 MAX(SAL)=2850" → BLAKE.SAL=2850 → 참 -- SMITH(20번) 행 → 서브쿼리는 "20번 부서의 MAX(SAL)=3000" → SMITH.SAL=800 → 거짓 -- 각 사원마다 '자기 부서 기준' 으로 판단하므로 정확하다. -- -- ⚠️ 15강 IN 방식과의 차이 -- 15강: SAL IN (5000, 3000, 2850) → 부서 구분 없이 이 값이면 통과 (부정확 가능) -- 16강: 자기 부서의 MAX 와만 비교 → 정확
SQL
복사

3) 비상관 vs 상관 서브쿼리 비교

비상관 서브쿼리 (15강)
상관 서브쿼리 (오늘)
메인 참조
❌ 안 함
✅ 메인 컬럼 참조
실행 횟수
한 번
메인 행마다 반복
실행 순서
서브쿼리 → 메인
메인 행 하나 → 서브쿼리 → … 반복
예
WHERE SAL > (SELECT AVG(SAL) FROM EMP)
WHERE SAL = (SELECT MAX(SAL) FROM EMP WHERE DEPTNO=E.DEPTNO)

5. EXISTS ⭐⭐

1) EXISTS 는 대부분 상관 서브쿼리

-- ============================================================ -- 【이해용 예제】 소속 사원이 있는 부서만 (EXISTS) ★ -- ============================================================ SELECT D.DEPTNO, D.DNAME FROM DEPT D WHERE EXISTS ( SELECT 1 FROM EMP E WHERE E.DEPTNO = D.DEPTNO ); -- 바깥 D.DEPTNO 참조 = 상관 -- DEPTNO DNAME -- ------ ---------- -- 10 ACCOUNTING -- 20 RESEARCH -- 30 SALES → 3건 (40번 제외) -- -- ⭐ 각 부서 행마다 "그 부서에 사원이 있나?" 를 확인해 하나라도 있으면 통과.
SQL
복사

2) NOT EXISTS — 사원이 없는 부서

-- ============================================================ -- 【시험용 예제】 소속 사원이 하나도 없는 부서 ★★ -- ============================================================ SELECT D.DEPTNO, D.DNAME FROM DEPT D WHERE NOT EXISTS ( SELECT 1 FROM EMP E WHERE E.DEPTNO = D.DEPTNO ); -- DEPTNO DNAME -- ------ ---------- -- 40 OPERATIONS → 1건 -- -- ⭐ NOT EXISTS 는 '존재하지 않으면 참'. NULL 비교를 하지 않아 -- 15강의 NOT IN + NULL 함정(0건 문제)을 원천적으로 피한다. -- -- 같은 결과를 NOT IN 으로 쓰면 위험하다 SELECT DEPTNO, DNAME FROM DEPT WHERE DEPTNO NOT IN ( SELECT DEPTNO FROM EMP ); -- EMP.DEPTNO 에 NULL 없으면 OK -- → 이 경우는 EMP.DEPTNO 에 NULL 이 없어 우연히 동작하지만, -- NULL 가능성이 있으면 NOT EXISTS 가 안전하다.
SQL
복사

6. 스칼라 · 인라인뷰 · 상관 서브쿼리 정리

종류
위치
역할
반환
스칼라 서브쿼리
SELECT 절
컬럼처럼 값 하나
1행 1컬럼
인라인 뷰
FROM 절
임시 테이블
여러 행·컬럼
상관 서브쿼리
주로 WHERE
행마다 판단
조건에 따라

7. 출제 포인트 한눈에 정리

#
꼭 외울 것
핵심
1
스칼라 서브쿼리 위치
SELECT 절
2
스칼라 서브쿼리 반환
1행 1컬럼 (아니면 오류) ⭐
3
스칼라 서브쿼리 + 매칭 없음
NULL 반환 (LEFT JOIN 효과) ⭐
4
스칼라 서브쿼리 vs 조인
상호 변환 가능
5
인라인 뷰 위치
FROM 절
6
인라인 뷰 ORDER BY
가능 (WHERE 서브쿼리는 불가) ⭐
7
인라인 뷰 별칭
계산식 컬럼엔 별칭 필수
8
인라인 뷰 활용
Top-N 쿼리 기반 (21강)
9
상관 서브쿼리
서브쿼리가 메인 컬럼 참조 ⭐
10
상관 서브쿼리 실행
메인 행마다 반복
11
비상관 vs 상관
한 번 실행 vs 반복 실행
12
부서별 최고급여자
상관 서브쿼리가 정확 ⭐
13
EXISTS
대부분 상관 서브쿼리
14
NOT EXISTS
NULL 함정 없음 (NOT IN 대체)

9. 확인 문제

Q1. 스칼라 서브쿼리는 어느 절에 위치하며, 무엇을 반환해야 하는가?
정답 보기
Q2. 스칼라 서브쿼리가 매칭되는 값을 못 찾으면 어떻게 되는가?
정답 보기
Q3. WHERE절 서브쿼리와 인라인 뷰의 가장 큰 차이는?
정답 보기
Q4. NOT EXISTS 가 NOT IN 보다 안전한 상황은?
정답 보기