•
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 보다 안전한 상황은?
정답 보기






안 함
메인 컬럼 참조