본문 바로가기
C.W.K.
Stream
Lesson 15 of 16 · published

행을 접지 않는 윈도 함수

~14 min · queries, windows

Level 0스키마 새싹
0 XP0/86 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

각 행을 남긴 채 주변을 계산해

GROUP BY는 여러 행을 한 행으로 접지만 윈도 함수는 원래 행을 그대로 둔 채 순위, 누적합, 이동 평균을 붙여. 그래서 주문 하나하나와 고객별 누적 금액을 같은 결과에서 볼 수 있어.

PARTITION과 ORDER가 계산의 창을 정해

SUM(total) OVER (PARTITION BY user_id ORDER BY placed_at)는 사용자마다 시간순 누적합을 계산해. 창의 경계를 명시하지 않으면 동점 처리 때문에 예상과 달라질 수 있어.

프레임은 현재 행 주변의 범위야

ROWS BETWEEN 6 PRECEDING AND CURRENT ROW는 현재 행과 앞선 6행, 곧 모두 7행을 대상으로 삼아. 날짜가 빠진 날이 있다면 7일과 7행은 다르다는 점을 기억해. 3행 이동 평균을 구할 때도 같은 원리야.

Code

누적 합계와 고객별 평균·sql
-- 고객당 running total
SELECT u.name, o.placed_at, o.total,
       SUM(o.total) OVER (
         PARTITION BY u.id
         ORDER BY o.placed_at
       ) AS running_total
FROM   users u
JOIN   orders o ON o.user_id = u.id
ORDER  BY u.name, o.placed_at;
고객 평균과의 차이·sql
SELECT u.name, o.total,
       AVG(o.total) OVER (PARTITION BY u.id)         AS customer_avg,
       o.total - AVG(o.total) OVER (PARTITION BY u.id) AS diff_from_avg
FROM   users u
JOIN   orders o ON o.user_id = u.id;
7일 이동 평균·sql
SELECT date, revenue,
       AVG(revenue) OVER (
         ORDER BY date
         ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
       ) AS moving_avg_7d
FROM daily_revenue
ORDER BY date;
재사용할 윈도 프레임에 이름 붙이기·sql
SELECT id, customer_id, total,
       SUM(total)   OVER w  AS running_total,
       AVG(total)   OVER w  AS running_avg,
       COUNT(*)     OVER w  AS running_count
FROM   orders
WINDOW w AS (PARTITION BY customer_id ORDER BY placed_at);

External links

Exercise

사용자마다 가장 최근 주문 3개와 전체 기간의 누적 지출액을 반환하는 질의를 작성해. 누적 합계에는 윈도 함수를, 사용자별 행 제한에는 ROW_NUMBER를 써.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.