running aggregate frame

누적 집계는 정렬된 행마다 프레임을 전진시킨다

SUM() OVERORDER BY를 넣으면 전체 합계가 아니라 현재 행까지의 윈도우 프레임을 집계합니다. 행 수는 유지되고, 각 행 옆에 그 시점의 누적값이 붙습니다.

explicit ROWS frame

행 단위 누적을 의도하면 프레임을 명시한다

SELECT order_date, order_id, amount,
       SUM(amount) OVER (
         ORDER BY order_date, order_id
         ROWS BETWEEN UNBOUNDED PRECEDING
              AND CURRENT ROW
       ) AS running_total,
       AVG(amount) OVER (
         ORDER BY order_date, order_id
         ROWS BETWEEN UNBOUNDED PRECEDING
              AND CURRENT ROW
       ) AS running_avg
FROM daily_sales;

ORDER BY만 두면 DBMS 기본 프레임이 적용됩니다. 같은 날짜가 여러 행이면 peer가 함께 묶일 수 있으므로, 행마다 전진하는 누적합은 ROWS와 보조 정렬 기준을 함께 둡니다.

5 rows in, 5 rows out

현재 행까지의 프레임이 결과 열이 된다

#101 100
#102 300
#103 350
#104 650
#105 800
order_date id amount ROWS frame SUM AVG
2024-01-01 #101 100 #101 100 100
2024-01-01 #102 200 #101..#102 300 150
2024-01-02 #103 50 #101..#103 350 116.7
2024-01-03 #104 300 #101..#104 650 162.5
2024-01-03 #105 150 #101..#105 800 160
default RANGE caution

같은 정렬값은 한 번에 묶일 수 있다

ORDER BY order_date만 두면 같은 날짜 행이 peer로 취급되어 첫 번째 2024-01-01 행부터 누적합이 300처럼 보일 수 있습니다. “현재 행까지”라는 말이 날짜 단위인지 행 단위인지 먼저 정해야 합니다.

stable ROWS frame

행 단위 누적은 보조 정렬이 필요하다

ORDER BY order_date, order_id ROWS ... CURRENT ROW처럼 동률을 깨는 키를 추가하면 같은 입력을 여러 번 실행해도 누적 순서가 흔들리지 않습니다.

ORDER BY date 동일 날짜가 peer로 묶여 첫 행부터 300이 될 수 있다.
ORDER BY date, id 보조 키가 행 순서를 고정해 100, 300으로 전진한다.
ROWS frame 현재 물리 행까지라는 의도를 SQL에 직접 남긴다.

누적 열은 네 가지 결정을 고정해야 재현된다

1 group

어디서 다시 0부터 누적할지 정한다

고객별, 계정별, 월별 누적이면 PARTITION BY가 먼저다.

2 order

동률을 깨는 보조 정렬 키를 둔다

order_date만으로 부족하면 order_id를 붙인다.

3 frame

행 단위라면 ROWS를 명시한다

RANGE peer 묶음이 아니라 현재 물리 행까지 누적한다.

4 policy

NULL과 결과 행 수를 확인한다

윈도우 집계는 행을 줄이지 않으며 NULL 처리 규칙은 보고서에 남긴다.

partition

그룹별 누적이면 PARTITION 추가

고객별 누적 구매액은 PARTITION BY customer_id ORDER BY order_date, order_id 로 프레임을 고객 안에서만 전진시킵니다.

null policy

NULL amount 정책을 정한다

SUMAVG는 NULL을 무시합니다. 누락을 0으로 볼지 제외할지는 보고 규칙에 맞춰 명시합니다.

not GROUP BY

행을 줄이지 않는다

윈도우 집계는 입력 행을 접지 않고 계산 열을 붙입니다. 결과 행 수가 줄어야 한다면 GROUP BY가 맞습니다.