
SQL 중급까지 학습했다면 이제 본격적인 데이터 분석 단계에서 자주 사용되는 윈도우 함수(Window Functions) 와 서브쿼리(Subquery) 를 학습해야 합니다.
윈도우 함수는 기존 GROUP BY로는 표현하기 어려운 누적값, 순위, 이동평균, 비율 계산 등을 매우 쉽게 만들 수 있는 고급 SQL 기능입니다.
서브쿼리는 쿼리 안에서 또 다른 쿼리를 실행하여 결과를 비교, 필터링, 집계할 때 활용합니다.
둘 다 실무 분석에서 매우 많이 등장하는 고급 SQL 기능으로, 이 글에서는 핵심 개념과 예제를 중심으로 설명합니다.
1. 윈도우 함수(Window Functions) 기본 개념
윈도우 함수는 다음과 같은 패턴으로 사용됩니다.
function() OVER (
PARTITION BY column
ORDER BY column
ROWS BETWEEN ...
)
주요 기능
- 누적합(Cumulative Sum)
- 순위(RANK, DENSE_RANK, ROW_NUMBER)
- 이전 값/다음 값 (LAG, LEAD)
- 이동평균(Moving Average)
- 전체 대비 비율 계산
GROUP BY와 달리 데이터가 집약되지 않고 원본 행이 그대로 유지되는 것이 핵심 차이점입니다.
2. 윈도우 함수 예제
2-1. 행 번호 붙이기: ROW_NUMBER()
SELECT
title,
release_year,
ROW_NUMBER() OVER (ORDER BY release_year) AS row_num
FROM films;
결과 예시:
| Film A | 1980 | 1 |
| Film B | 1981 | 2 |
| … | … | … |
2-2. 순위 매기기: RANK(), DENSE_RANK()
SELECT
title,
gross,
RANK() OVER (ORDER BY gross DESC) AS gross_rank
FROM films;
- RANK() : 동점 순위 발생 시 건너뛰기
- DENSE_RANK() : 순위 건너뛰지 않음
2-3. 누적합(Cumulative Sum)
SELECT
release_year,
gross,
SUM(gross) OVER (ORDER BY release_year) AS cumulative_gross
FROM films;
결과 예시:
| 1990 | 500000 | 500000 |
| 1991 | 700000 | 1,200,000 |
| 1992 | 800000 | 2,000,000 |
2-4. PARTITION BY 사용: 연도별 순위 구하기
SELECT
title,
release_year,
gross,
RANK() OVER (PARTITION BY release_year ORDER BY gross DESC) AS rank_in_year
FROM films;
→ 같은 연도끼리 묶어서 순위를 매깁니다.
2-5. 이전 행과 비교: LAG()
SELECT
release_year,
gross,
LAG(gross, 1) OVER (ORDER BY release_year) AS previous_year_gross
FROM films;
이전의 gross 값을 함께 확인할 수 있습니다.
2-6. 이동 평균(Moving Average)
SELECT
release_year,
gross,
AVG(gross) OVER (
ORDER BY release_year
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS moving_avg_3
FROM films;
→ 최근 3개 영화의 평균 계산
3. 서브쿼리(Subquery) 기본 개념
서브쿼리는 SQL 문 안에 포함된 다른 쿼리를 의미합니다. 활용 방식은 크게 세 가지입니다.
1) SELECT 절에서 사용 (스칼라 서브쿼리)
2) FROM 절에서 사용 (파생 테이블)
3) WHERE 절에서 사용 (조건 필터링)
4. 서브쿼리 예제
4-1. WHERE 절에서: 특정 조건을 가진 행만 조회
예: 전체 평균보다 높은 gross를 가진 영화만 조회
SELECT title, gross
FROM films
WHERE gross > (
SELECT AVG(gross)
FROM films
);
4-2. IN 서브쿼리: 특정 감독의 영화만 조회
SELECT title, director
FROM films
WHERE director IN (
SELECT name
FROM people
WHERE role = 'Director'
);
4-3. NOT IN 서브쿼리: 데이터 제외
SELECT title
FROM films
WHERE title NOT IN (
SELECT title
FROM banned_films
);
4-4. FROM 절 서브쿼리: 파생 테이블 사용
연도별 평균 gross를 계산한 뒤 다시 필터링할 때 사용합니다.
SELECT *
FROM (
SELECT
release_year,
AVG(gross) AS avg_gross
FROM films
GROUP BY release_year
) AS yearly_stats
WHERE avg_gross > 100000000;
4-5. SELECT 절 서브쿼리: 한 행에 요약치 포함
SELECT
title,
gross,
(SELECT AVG(gross) FROM films) AS global_avg
FROM films;
모든 행에 전체 평균을 함께 보여 줍니다.
4-6. 윈도우 함수와 서브쿼리 혼합
가장 흔한 실무 패턴 중 하나입니다.
SELECT *
FROM (
SELECT
title,
release_year,
gross,
RANK() OVER (PARTITION BY release_year ORDER BY gross DESC) AS year_rank
FROM films
) ranked
WHERE year_rank = 1;
→ 연도별 최고 매출 영화만 조회
SQL에서 윈도우 함수(Window Functions) 와 서브쿼리(Subquery) 는 데이터 분석 능력을 한 단계 확장시키는 핵심 기능입니다.
윈도우 함수는 “요약하면서도 행을 유지하는” 분석을 가능하게 만들고, 서브쿼리는 복잡한 조건과 비교 연산을 구조적으로 해결합니다.
특히 누적합, 순위, 전년 대비 계산, 이동평균, 파생 테이블, IN/NOT IN 서브쿼리는 기업 데이터 분석에서 매우 자주 등장하므로 반드시 익혀두어야 합니다.
'Programming' 카테고리의 다른 글
| 머신러닝 완전 입문 가이드 2편: 분류(Classification)와 결정트리·앙상블 알고리즘 완전 이해하기 (0) | 2025.12.08 |
|---|---|
| 머신러닝 완전 입문 가이드 1편: 머신러닝 개념과 학습 방식 이해하기 (0) | 2025.12.08 |
| SQL 중급 완전 정리: ORDER BY, GROUP BY, HAVING, INNER JOIN (0) | 2025.12.08 |
| SQL 기초 완전 정리: SELECT부터 WHERE, DISTINCT, LIKE, NULL, 집계함수까지 (0) | 2025.12.08 |
| 파이썬 가상환경(Mac & Windows) 설정 완전 가이드 (0) | 2025.12.08 |