윈도우 함수는 행(row) 단위의 집계, 누적, 이동 평균 등 다양한 분석을 효율적으로 수행할 수 있는 SQL 기능이다. 특히 ROWS, RANGE, PARTITION BY는 윈도우 프레임을 정의할 때 핵심적으로 사용되며, 각각의 개념과 차이를 명확히 이해하는 것이 중요하다.
| 키워드 | 기준 | 동작 방식 |
|---|---|---|
| ROWS | 행의 개수 | 물리적으로 몇 개의 "행"을 포함할지를 기준으로 프레임을 설정 |
| RANGE | 값의 범위 | ORDER BY된 컬럼의 "값" 기준 범위로 프레임을 설정 |
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
현재 행부터 위로 3개의 행까지 포함하는 총 4개의 윈도우 프레임을 구성한다.
특징:
RANGE BETWEEN INTERVAL 7 DAY PRECEDING AND CURRENT ROW
현재 행의 기준값을 중심으로 값의 범위 내에 있는 모든 행을 포함한다. 날짜나 수치형 값이 중복될 경우 여러 행이 추가될 수 있음.
주의사항:
| 키워드 | 의미 |
|---|---|
| n PRECEDING | 현재 행 기준 n개 이전 행 |
| n FOLLOWING | 현재 행 기준 n개 이후 행 |
| CURRENT ROW | 현재 행 자체 포함 |
예시:
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
→ 현재 행 포함, 이전 6개 행까지 포함 (총 7개 행)
PARTITION BY는 그룹화된 범위 내에서 윈도우 함수를 수행할 때 사용된다. 사용자별, 브랜드별, 지역별 등으로 구간을 나누어 독립적인 집계를 할 수 있게 해준다.
SELECT
item_brand,
order_date,
SUM(1) OVER (
PARTITION BY item_brand
ORDER BY order_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS brand_order_count
FROM orders;
→ 각 브랜드별로 주문일 기준 누적 주문 수를 계산
WITH daily_spend AS (
SELECT
buyer_id,
order_date,
SUM(price) AS daily_amount
FROM orders
GROUP BY buyer_id, order_date
)
SELECT
buyer_id,
order_date,
AVG(daily_amount) OVER (
PARTITION BY buyer_id
ORDER BY order_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS avg_7d
FROM daily_spend;
→ 각 사용자 기준 최근 7일 평균을 계산 (슬라이딩 윈도우 방식)
SELECT
buyer_id,
amount,
RANK() OVER (
PARTITION BY buyer_id
ORDER BY amount DESC
) AS purchase_rank
FROM orders;
→ 사용자별로 가장 큰 금액 순위 부여
| 상황 | ROWS 사용 추천 | RANGE 사용 추천 |
|---|---|---|
| 중복값 있음 | ✅ | ⚠️ 주의 |
| 정확한 행 수 제어 | ✅ | ❌ |
| 시간 기반 집계 | ✅ | ⚠️ (값 기준 주의) |
| 대용량 데이터 | ✅ (성능 안정적) | ❌ (비효율 가능) |
PARTITION BY는 특히 그룹화된 누적합, 이동 평균, 랭킹 처리 시 필수적이다. 실무에서는 주로 ROWS + PARTITION BY 조합을 통해 성능과 예측 가능성을 모두 확보한다.
이러한 패턴은 데이터 웨어하우스, BI 리포팅, ETL 파이프라인 집계 단계에서 매우 자주 활용되므로, 데이터 엔지니어링의 핵심 툴셋으로 숙지해 두어야 한다.