상상해봐: 네가 회사의 수입을 관리하거나, 인터넷 쇼핑몰 매출을 보거나, 아니면 그냥 1년 동안 네가 쓴 돈을 분석하고 있다고 해. 단순히 매달 수입이나 지출만 보는 게 아니라, 그게 달마다 어떻게 누적되는지도 알고 싶을 거야.
일반적인 집계 함수(GROUP BY)로는 이게 안 돼 — 데이터가 그룹별로 묶여서 그룹마다 한 줄만 나오거든. 근데 우리는 매달 그리고 누적 합계도 같이 보고 싶잖아? 이럴 때 SUM()이 윈도우 함수랑 같이 등장하는 거지.
누적 합계에 윈도우 함수 쓰는 기본
윈도우 함수는 윈도우 프레임별로 집계 연산을 할 수 있게 해줘. 그래서 각 행마다 값을 더하면서도, 다른 행은 안 사라져. GROUP BY 때문에 데이터가 사라질 일 없음!
SUM() 윈도우 함수 문법
누적 합계 쓸 때 기본 템플릿은 이래:
SELECT
column_name,
SUM(column_name) OVER (PARTITION BY partition_column ORDER BY order_column) AS cumulative_sum
FROM
table_name;
여기서:
SUM(column_name)— 값을 더해줌.OVER()— 누적 계산할 윈도우를 지정.PARTITION BY— 데이터를 그룹으로 나눔(선택사항).ORDER BY— 윈도우 안에서 행의 순서를 정함.
예시: 월별 누적 수입
네 수입 테이블이 있다고 해보자:
| 월 | 수입 |
|---|---|
| 2023-01 | 1000 |
| 2023-02 | 1500 |
| 2023-03 | 2000 |
매달 수입 그리고 누적 합계를 같이 보고 싶어. SQL 쿼리를 이렇게 짜보자:
SELECT
월,
수입,
SUM(수입) OVER (ORDER BY 월) AS 누적_수입
FROM
수입들;
결과:
| 월 | 수입 | 누적_수입 |
|---|---|---|
| 2023-01 | 1000 | 1000 |
| 2023-02 | 1500 | 2500 |
| 2023-03 | 2000 | 4500 |
어떻게 돌아가는지 보자:
ORDER BY 월이OVER()안에 있으니까 PostgreSQL이 행을 시간 순서대로 봐.- 각 행마다, 그 행까지의 모든 이전 행(그리고 현재 행) 합계를 계산해.
여기서 중요한 건, 첫 번째 행은 SUM()이 첫 번째 행만 더하고, 두 번째는 두 행, 세 번째는 세 행을 더한다는 거야. 그래서 월 정렬 순서가 진짜 중요해!
예시: 지역별 누적 수입
만약 네가 지역별 판매 테이블이 있다면, 일부는 이렇게 생겼을 거야:
| 지역 | 월 | 수입 |
|---|---|---|
| 북부 | 2023-01 | 1000 |
| 북부 | 2023-02 | 1500 |
| 남부 | 2023-01 | 2000 |
| 남부 | 2023-02 | 2500 |
이제 각 지역별로 누적 수입을 따로 계산하고 싶어:
SELECT
지역,
월,
수입,
SUM(수입) OVER (PARTITION BY 지역 ORDER BY 월) AS 누적_수입
FROM
판매들;
결과는 이렇게 나와:
| 지역 | 월 | 수입 | 누적_수입 |
|---|---|---|---|
| 북부 | 2023-01 | 1000 | 1000 |
| 북부 | 2023-02 | 1500 | 2500 |
| 남부 | 2023-01 | 2000 | 2000 |
| 남부 | 2023-02 | 2500 | 4500 |
이제 각 지역별로 따로 분석되는 거지(PARTITION BY 지역). 그리고 지역 안에서는 시간 순서대로 정렬(ORDER BY 월).
이동 평균 (AVG())
오케이, 누적 합계도 좋지만, 최근 3개월 트렌드를 보고 싶을 땐? 그럴 땐 이동 평균이 딱이야.
예시: 수입 이동 평균
다시 수입들 테이블을 쓴다고 해보자. 데이터는 이래:
| 월 | 수입 |
|---|---|
| 2023-01 | 1000 |
| 2023-02 | 1500 |
| 2023-03 | 2000 |
| 2023-04 | 2500 |
3개월 이동 평균을 계산하는 쿼리는 이렇게:
SELECT
월,
수입,
AVG(수입) OVER (
ORDER BY 월
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS 이동_평균
FROM
수입들;
결과:
| 월 | 수입 | 이동_평균 |
|---|---|---|
| 2023-01 | 1000 | 1000 |
| 2023-02 | 1500 | 1250 |
| 2023-03 | 2000 | 1500 |
| 2023-04 | 2500 | 2000 |
설명:
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW는 PostgreSQL한테 현재 행이랑 이전 두 행까지 평균을 내라고 시키는 거야.- 그래서 각 월마다 최근 3개월 평균 수입을 볼 수 있어.
즉, 각 행마다 3행짜리 윈도우(현재+이전 두 개)를 잡고, 그걸로 평균을 내는 거지. 진짜 편함.
ORDER BY의 역할과 영향
윈도우 함수는 행 순서가 진짜 중요해. 순서가 잘못됐거나(아예 없거나) 하면 결과가 이상하게 나올 수 있어.
예시: ORDER BY 없어서 생기는 실수
OVER()에서 ORDER BY를 빼면, 누적 합계 대신 모든 행의 합계를 각 행마다 보여주게 돼:
SELECT
월,
수입,
SUM(수입) OVER () AS 잘못된_누적_합계
FROM
수입들;
결과:
| 월 | 수입 | 잘못된누적합계 |
|---|---|---|
| 2023-01 | 1000 | 7000 |
| 2023-02 | 1500 | 7000 |
| 2023-03 | 2000 | 7000 |
| 2023-04 | 2500 | 7000 |
행 순서가 없으니까, 누적 합계 대신 그냥 전체 합계를 각 행마다 보여주는 거야.
실전 활용 예시
수입 분석:
- 누적 합계로 회사 매출이나 수입이 어떻게 늘어나는지 추적할 수 있어.
- 이동 평균은 "노이즈" 없이 깔끔한 트렌드를 볼 수 있게 해줘.
금융 모델링:
은행이나 금융 회사들은 윈도우 함수로 상환, 부채 증가, 기타 지표를 분석해.
시계열 데이터 분석:
온라인 유저 수, 페이지뷰, 매출 등 시간에 따라 변하는 데이터는 SUM()이랑 AVG()로 분석하기 딱 좋아.
GO TO FULL VERSION