| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 금융 플랫폼
- Python
- alias
- join
- programmers
- 도서추천
- SubQuery
- having
- Round
- IN
- 금융IT
- is null
- count
- MySQL
- where
- ifnull
- inner join
- date_format
- order by
- 날짜 포맷
- IS NOT NULL
- GROUP BY
- 해외결제
- SQL
- 투자자산운용사
- MAX
- 트래블테크
- LIMIT
- IELTS
- 서브쿼리
- Today
- Total
Every Step Matters
[SQL] 서브 쿼리 (SubQuery) : (3) 인라인 뷰 (FROM절에 작성) 본문

오늘은 서브 쿼리 중에서도 인라인 뷰에 대해 알아보도록 하자.
서브 쿼리 시리즈의 다른 글은 아래 링크를 참고하길 바란다.
[SQL] 서브 쿼리 (SubQuery) : (1) 기본 개념과 주요 예시
1. 서브 쿼리란?하나의 SQL문 안에 포함되어 있는 SQL문서브 쿼리를 포함하는 SQL을 외부 쿼리(outer query) 또는 메인 쿼리라고 부르며, 서브 쿼리는 내부 쿼리(inner query)라고도 부른다.‘어떤 데이터
imnyoungit.tistory.com
[SQL] 서브 쿼리 (SubQuery) : (2) 중첩 서브 쿼리 (WHERE절에 작성)
오늘은 서브 쿼리 중에서도 가장 많이 사용되는 "중첩 서브 쿼리"에 대해 알아보려고 한다.서브 쿼리의 전반적인 개념 설명은 아래 링크를 참고하길 바란다. [SQL] 서브 쿼리 (SubQuery) : (1) 기본 개
imnyoungit.tistory.com
1. 인라인 뷰(Inline View)란?
서브쿼리는 값이 올 수 있는 곳이면 어디나 올 수 있지만, 주로 다음 세 곳에서 사용한다.
1) WHERE절 : 조건에 사용할 값을 찾는다.
2) SELECT절의 필드 목록 : 출력할 값을 찾는다.
3) FROM절 : 출력 대상 테이블을 생성한다.
이때 WHERE절이나 SELECT절의 서브쿼리는 둘 다 값을 리턴하는 반면, FROM 절의 서브쿼리는 값이 아닌 테이블을 리턴한다.
FROM절은 조회 대상 테이블을 명시하는 절이므로, 생각해보면 당연한 부분이다.
이렇게 FROM절에 오는 서브쿼리를 "인라인뷰(Inline View)"라고 부른다.
인라인 뷰는 SQL문이 실행될 때만 임시적으로 생성되는 뷰이기 때문에 데이터베이스에 해당 정보가 저장되지 않는다.(인라인이라고 부르는 이유!) 그래서 동적 뷰(Dynamic View)라고도 한다.
2. 인라인 뷰의 기본 형태와 사용 이유
인라인 뷰의 기본 형태는 아래와 같다.
SELECT 컬럼
FROM (
SELECT ...
FROM ...
) 별칭;
⚠️ 이때 반드시 별칭(ALIAS)이 있어줘야 하는데, 그 이유는 서브 쿼리의 결과가 SQL 문법적으로 테이블처럼 취급되기 때문이다.
인라인뷰의 사용 이유
[ 핵심 사용 이유 3가지 ]
1. 집계 결과를 다시 조회 조건으로 쓰고 싶을 때
2. GROUP BY 때문에 메인 쿼리가 복잡해질 때
3. 서브쿼리 결과를 여러 번 참조하고 싶을 때
인라인뷰는 조건을 독립적이고 순차적으로 해결할 수 있으므로 아주 유용하다.

예시와 함께 살펴보자
예시 : FISH_INFO
다음과 같은 컬럼으로 구성된 FISH_INFO 테이블이 있다고 하자. (프로그래머스의 FISH_INFO 테이블과 동일)
| Column name | Type | Nullable | Description |
| ID | INTEGER | FALSE | 잡은 물고기의 ID |
| FISH_TYPE | INTEGER | FALSE | 물고기의 종류(숫자) |
| LENGTH | FLOAT | TRUE | 잡은 물고기의 길이(cm) |
| TIME | DATE | FALSE | 물고기를 잡은 날짜 |
잡은 물고기의 길이가 10cm 이하일 경우에는 LENGTH가 NULL 이며, LENGTH에 NULL 만 있는 경우는 없다.
1) 집계 결과를 다시 조회 조건으로 쓰고 싶은 경우
문제 : 문고기 종류별 평균 길이를 구한 뒤, 평균 길이가 30cm 이상인 물고기 종류만 조회
SELECT fish_type, avg_length
FROM ( -- 평균 길이를 컬럼으로 포함하는 가상 테이블 생성
SELECT fish_type, AVG(length) AS avg_length
FROM fish_info
GROUP BY fish_type
) f
WHERE avg_length >= 30; -- 해당 가상 테이블의 평균 길이 이용
2) GROUP BY 때문에 메인 쿼리가 복잡해질 경우
문제 : 물고기 종류별 '평균 길이'와 '잡힌 횟수'를 조회. 이때 평균 길이 기준으로 정렬하기.
SELECT fish_type, avg_length, fish_count
FROM (
SELECT fish_type,
AVG(length) AS avg_length,
COUNT(*) AS fish_count
FROM fish_info
GROUP BY fish_type
) f
ORDER BY avg_length DESC;
이 경우는 서브 쿼리를 이용하지 않고 아래처럼도 충분히 해결이 가능하지만, 인라인 뷰를 사용하는 경우 각 쿼리의 역할이 명확해져 조건을 추가하기 용이하다.(ex. "평균 길이가 30 이상인 물고기 종류만 조회" 조건 추가) 즉, 인라인 뷰를 사용하는 경우 확장 가능성이 좋다!
SELECT fish_type, AVG(length) AS avg_length, COUNT(*) AS fish_count FROM fish_info GROUP BY fish_type;
3) 서브쿼리 결과를 여러 번 참조하고 싶을 때
문제 : 물고기 종류별 평균 길이를 계산하여 평균 길이가 40 이상이면 ‘대형’, 25 이상 40 미만이면 ‘중형’, 25 미만이면 ‘소형’으로 분류하여 출력하기.
SELECT fish_type, avg_length,
CASE
WHEN avg_length >= 40 THEN '대형'
WHEN avg_length >= 25 THEN '중형'
ELSE '소형'
END AS size_grade
FROM (
SELECT fish_type, AVG(length) AS avg_length
FROM fish_info
GROUP BY fish_type
) f;
⚠️ 주의 : SELECT 절에서 정의한 별칭은 같은 같은 SELECT 절에서 바로 사용할 수 없다.
아래 쿼리는 논리적으로는 맞아 보이지만 실행되지 않는다.
=> SQL 실행 순서상 CASE 문이 평가되는 시점에는 avg_length라는 컬럼은 아직 존재하지 않기 때문!SELECT fish_type, AVG(length) AS avg_length, CASE WHEN avg_length >= 40 THEN '대형' WHEN avg_length >= 25 THEN '중형' ELSE '소형' END AS size_grade FROM fish_info GROUP BY fish_type;
따라서 인라인 뷰를 통해 미리 평균을 계산하고 avg_length 컬럼을 만들어야 한다!!
이처럼 FROM 절에서 집계 서브쿼리를 한 번만 수행하고, 결과를 여러 컬럼에서 재사용할 수 있기 때문에 가독성과 성능을 모두 개선할 수 있다.
인라인 뷰는 FISH_INFO처럼 단일 테이블만 있더라도, 집계·계산 결과를 단계적으로 만들고 재사용하기 위해 꼭 필요한 구조다.
Reference
'Database > SQL' 카테고리의 다른 글
| [프로그래머스 SQL Lv.4] 서울에 위치한 식당 목록 출력하기 (MySQL) (0) | 2026.01.07 |
|---|---|
| [SQL] 서브 쿼리 (SubQuery) : (4) 스칼라 서브 쿼리 (단 하나의 값만 반환, SELECT절에 작성) (0) | 2026.01.07 |
| [SQL] 서브 쿼리 (SubQuery) : (2) 중첩 서브 쿼리 (WHERE절에 작성) (0) | 2026.01.06 |
| [프로그래머스 SQL Lv.3] 업그레이드 할 수 없는 아이템 구하기 (MySQL) (0) | 2026.01.05 |
| [프로그래머스 SQL Lv.2] ROOT 아이템 구하기 (MySQL) (0) | 2026.01.05 |