4. 비개발자를 위한 SQL 윈도우 함수 완전 정복 – 순위, 누적 합계, 전후 비교 실습
많은 비개발자들이 SQL의 SELECT와 GROUP BY만으로 대부분의 데이터를 처리할 수 있다고 생각하지만, 실무에 들어가면 ‘순위를 매기고 싶다’, ‘이전 달과 비교하고 싶다’, ‘누적 매출을 보고 싶다’ 같은 요구가 생긴다. 이런 분석은 GROUP BY로는 불가능하고, 복잡한 서브쿼리로도 어렵게 구현된다. 이때 필요한 것이 바로 윈도우 함수(Window Function)다. 윈도우 함수는 집계와는 다른 방식으로 행 단위의 비교 분석을 가능하게 해주며, SQL을 한 차원 더 깊이 이해하게 만들어 준다. 이 글에서는 윈도우 함수의 개념을 쉽게 풀고, 실무 예제를 통해 비개발자도 스스로 활용할 수 있도록 설명한다.
1. 윈도우 함수란?
윈도우 함수는 기존 SELECT 쿼리의 결과 집합 위에서, 특정 범위(창, window)를 설정하고 그 범위 안에서 연산을 수행하는 함수다. GROUP BY처럼 데이터를 묶지 않고, 행 하나하나에 결과가 붙는다는 점이 가장 큰 차이다.
📌 문법 구조:
SELECT 컬럼,
함수명() OVER (PARTITION BY ... ORDER BY ...) AS 별칭
FROM 테이블;
- PARTITION BY: 분석 범위를 설정하는 기준 (ex. 고객별, 월별)
- ORDER BY: 분석 내 정렬 기준
- 함수: ROW_NUMBER(), RANK(), SUM(), AVG(), LAG(), LEAD() 등
2. 예제 데이터 소개
이번 예제는 orders 테이블 하나만 사용한다.
orders 테이블
order_id | user_id | amount | order_date |
101 | 1 | 120000 | 2025-07-05 |
102 | 2 | 90000 | 2025-07-10 |
103 | 1 | 150000 | 2025-08-01 |
104 | 3 | 80000 | 2025-08-05 |
105 | 1 | 50000 | 2025-08-10 |
106 | 2 | 200000 | 2025-08-12 |
107 | 2 | 130000 | 2025-08-20 |
3. 실무 예제
예제 1: 사용자별 주문 순번 구하기 (ROW_NUMBER)
SELECT
user_id,
order_id,
amount,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY order_date
) AS order_rank
FROM orders;
결과 예시:
user_id | order_id | amount | order_rank |
1 | 101 | 120000 | 1 |
1 | 103 | 150000 | 2 |
1 | 105 | 50000 | 3 |
예제 2: 누적 매출 계산하기 (SUM + OVER)
SELECT
user_id,
order_date,
amount,
SUM(amount) OVER (
PARTITION BY user_id
ORDER BY order_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS cumulative_amount
FROM orders;
결과 예시:
user_id | order_date | amount | cumulative_amount |
1 | 2025-07-05 | 120000 | 120000 |
1 | 2025-08-01 | 150000 | 270000 |
1 | 2025-08-10 | 50000 | 320000 |
예제 3: 전 주문 금액과 비교하기 (LAG)
SELECT
user_id,
order_date,
amount,
LAG(amount) OVER (
PARTITION BY user_id
ORDER BY order_date
) AS prev_amount
FROM orders;
결과 예시:
user_id | order_date | amount | prev_amount |
1 | 2025-07-05 | 120000 | NULL |
1 | 2025-08-01 | 150000 | 120000 |
1 | 2025-08-10 | 50000 | 150000 |
예제 4: 사용자별 주문 금액 순위 매기기 (RANK)
SELECT
user_id,
amount,
RANK() OVER (
PARTITION BY user_id
ORDER BY amount DESC
) AS amount_rank
FROM orders;
결과 예시:
user_id | amount | amount_rank |
1 | 150000 | 1 |
1 | 120000 | 2 |
1 | 50000 | 3 |
📌 각 고객이 가장 비싼 주문이 무엇인지, 순위를 매겨 확인할 수 있다.
4. 윈도우 함수 vs GROUP BY
항목 | GROUP BY | 윈도우 함수 |
결과 개수 | 그룹당 1행 | 원본 행 그대로 유지 |
활용 예시 | 합계, 평균 등 요약 | 순위, 누적합, 전후 비교 등 분석용 |
집계 방식 | 전체 묶음 | 범위를 지정하여 유연하게 처리 |
실무 활용도 | 리포트, 요약 데이터 생성 | 마케팅 분석, 사용자 행동 패턴 분석 등 |
5. 실무 팁 & 활용 아이디어
- CRM 마케팅: 고객별 첫 구매 이후 변화 추적
- 매출 분석: 누적 성장률 확인, 목표 대비 추이 분석
- 리포트 자동화: 월별 실적 대비 순위, 증감률, 이전값 자동 출력
- 이커머스 분석: 재구매 시점 분석, 고액 구매자 패턴 분석
결론
윈도우 함수는 SELECT와 GROUP BY만으로는 절대 구현할 수 없는 고급 분석 기능을 제공한다. 하지만 그 문법은 생각보다 단순하고, 예제를 통해 익히면 비전공자도 실무에서 강력한 데이터 분석 도구로 활용할 수 있다. 이제 여러분도 SQL로 순위 분석, 누적 통계, 변화 추이 분석을 직접 해볼 수 있다.
다음 편에서는 실제 실무 리포트용 SQL을 설계하고 자동화하는 프로젝트 예제를 통해, 지금까지 배운 내용을 종합적으로 활용해보자.