[SQL] 데이터 분석의 치트키: 윈도우 함수(Window Function) DBMS별 완벽 가이드
SQL로 데이터를 추출하다 보면 "전체 매출 대비 개별 상품의 비중은?", "현재 행을 기준으로 이전 달과의 매출 차이는?"과 같은 질문에 직면하게 됩니다. 일반적인 GROUP BY만으로는 해결하기 까다로운 이런 문제들을 단 한 줄의 쿼리로 해결해 주는 것이 바로 윈도우 함수(Window Function)입니다.
오늘은 Oracle, MySQL, PostgreSQL 등 주요 DBMS에서 공통으로 사용할 수 있는 윈도우 함수의 핵심 개념과 실무 활용법, 그리고 각 DB별 주의사항을 정리해 보겠습니다.
1. 윈도우 함수란 무엇인가? (vs GROUP BY)
윈도우 함수는 행과 행 사이의 관계를 정의하기 위해 사용하는 함수입니다. 가장 큰 특징은 "행의 개수를 유지한다"는 점입니다.
- GROUP BY: 데이터를 그룹별로 집계하여 행의 수가 줄어듭니다. (예: 100개 행 → 5개 그룹)
- Window Function: 각 행에 대해 집계 결과를 계산하지만, 원래의 행을 그대로 유지합니다. (예: 100개 행 → 100개 행 유지 + 집계값 열 추가)
2. 윈도우 함수의 기본 문법
윈도우 함수는 항상 OVER 절을 동반합니다. ANSI 표준을 따르므로 대부분의 최신 DBMS에서 동일한 문법을 사용합니다.
SQL
SELECT 함수(인자) OVER (PARTITION BY 컬럼 ORDER BY 컬럼 WINDOWING 절)
FROM 테이블명;
- PARTITION BY: 소그룹화 기준 (전체 데이터를 특정 컬럼 기준으로 나눔)
- ORDER BY: 정렬 기준 (순위를 매기거나 누적합을 구할 때 필수)
- WINDOWING 절: 함수의 영향을 받는 행의 범위를 세밀하게 지정
3. 반드시 알아야 할 실무 핵심 함수
① 순위 결정 함수 (RANK Family)
데이터에 순번을 매길 때 사용하며, 동점자 처리 방식에 따라 선택합니다.
- ROW_NUMBER(): 중복 없이 고유한 순위 부여 (1, 2, 3, 4)
- RANK(): 동점 시 공통 순위 부여 후 다음 순위 건너뜀 (1, 2, 2, 4)
- DENSE_RANK(): 동점 시 공통 순위 부여 후 다음 순위 바로 이어짐 (1, 2, 2, 3)
② 행 간 이동 함수 (Value Family)
현재 행을 기준으로 앞뒤 행의 값을 가져오며, 시계열 데이터 분석의 핵심입니다.
- LAG(): 이전 행의 값을 가져옴 (전일 대비 증감 등)
- LEAD(): 다음 행의 값을 가져옴
③ 집계 함수 (Aggregate Family)
SUM, AVG 등을 사용하여 누적 합계를 구합니다.
SQL
-- 날짜별 누적 매출 합계
SELECT sale_date, daily_amount,
SUM(daily_amount) OVER (ORDER BY sale_date) as cumulative_sum
FROM sales;
4. DBMS별 미세한 차이 및 체크포인트
윈도우 함수는 표준 문법이지만, 사용 환경에 따라 반드시 체크해야 할 점들이 있습니다.
💡 MySQL (8.0 버전 이상 필수)
- 주의사항: MySQL은 5.7 이하 버전에서는 윈도우 함수를 지원하지 않습니다. 구버전에서는 사용자 정의 변수(@변수)를 써야 하는 복잡함이 있었으나, 8.0부터는 표준 문법을 완벽히 지원합니다.
- 성능: 대량 데이터에서 ORDER BY가 포함된 윈도우 함수 사용 시 인덱스 최적화가 중요합니다.
💡 Oracle (원조의 강력함)
- 특징: 가장 오랫동안 윈도우 함수를 지원해온 만큼 안정적입니다.
- 심화 기능: KEEP (DENSE_RANK FIRST/LAST) 같은 오라클 전용 함수를 통해 그룹 내 최댓값/최솟값을 가진 행의 다른 컬럼을 가져오는 등 더 강력한 기능을 제공합니다.
💡 PostgreSQL (표준의 정석)
- 특징: ANSI 표준을 가장 엄격하게 준수합니다.
- WINDOW 절 지원: 동일한 OVER 정의를 여러 번 써야 할 때, 하단에 WINDOW w AS (PARTITION BY ...) 형태로 별칭을 선언하여 재사용할 수 있어 가독성이 매우 좋습니다.
5. 성능 및 주의사항
- WHERE 절 사용 불가: 윈도우 함수는 SELECT 절이나 ORDER BY 절에서만 사용할 수 있습니다. 결과값을 조건으로 쓰고 싶다면 반드시 인라인 뷰(서브쿼리)로 감싸야 합니다.
- 리소스 소모: 윈도우 함수는 모든 행을 유지하며 정렬을 수행하므로 메모리 사용량이 많습니다. 실행 계획(EXPLAIN)을 통해 WindowAgg 단계에서의 부하를 체크하세요.
🏁 마무리하며
윈도우 함수를 능숙하게 다루게 되면, 수십 줄의 복잡한 서브쿼리와 조인을 단 몇 줄의 직관적인 코드로 바꿀 수 있습니다. 특히 시계열 데이터 분석이나 성과 지표 산출이 많은 실무 환경에서는 대체 불가능한 도구입니다.
오늘 정리한 내용을 바탕으로 여러분의 쿼리를 더욱 간결하고 강력하게 만들어 보세요!
'TECH > sql' 카테고리의 다른 글
| [SQL] 피벗(Pivot) 테이블 완벽 가이드: Oracle, MySQL, PostgreSQL별 구현 패턴 (0) | 2026.03.06 |
|---|---|
| [SQL] 대량 데이터 삭제 가이드: DELETE vs TRUNCATE vs DROP 완벽 비교 (0) | 2026.03.05 |
| [Oracle] 옵티마이저는 완벽하지 않다! SQL 힌트(Hint)로 실행 계획 제어하기 (0) | 2026.03.02 |
| [SQL 성능 최적화] EXISTS vs IN: 동작 원리부터 성능 차이까지 완벽 분석 (0) | 2026.03.01 |
| [Oracle/PostgreSQL] 뷰(View)가 너무 느리다면? 일반 뷰와 구체화 뷰(Materialized View) 완벽 비교 (0) | 2026.02.27 |