채널별 ARPPU와 순위 변동

난이도 어려움 · 권장 20분 · 출력 컬럼 month, channel, arppu, rnk, prev_rnk, rank_change
이 문제 직접 풀어보기 →

문제

월별·채널별 ARPPU(결제 유저 1인당 평균 결제액)를 구하고, 각 월 안에서 ARPPU 순위를 매긴 뒤 전월 대비 순위 변동을 구하세요. · ARPPU = 그 달 결제액 합계 / 그 달 결제한 순 유저 수, 소수점 둘째 자리 반올림 · 순위는 ARPPU 내림차순, 동점이면 같은 순위(RANK) · rank_change = 전월 순위 - 이번달 순위 (오르면 양수). 첫 달은 NULL · 월 오름차순, 순위 오름차순으로 정렬하세요.
정렬 month ASC, rnk ASC

쉽게 설명하면

반별 평균 점수로 등수를 매기고, 지난달 등수보다 올랐나 내렸나를 본다.

월채널평균등수지난달 등수변동
1월referral23,0001(없음)(없음)
2월referral23,200110
2월sns16,90043-1 (내려감)

변동 = 지난달 등수 − 이번달 등수. 등수가 1→4 로 내려가면 음수.

이렇게 푼다

  1. 월·채널별 평균을 먼저 만든다.
  2. 월 안에서 등수를 매긴다 — RANK() OVER (PARTITION BY 월 ORDER BY 평균 DESC).
  3. 채널별로 지난달 등수를 끌어온다 — LAG(등수) OVER (PARTITION BY 채널 ORDER BY 월).
  4. 지난달 등수 − 이번달 등수.

이것만 피하면 된다

자세히

묻는 것 · 윈도우를 두 단계로 겹쳐 쓸 줄 아는가.

풀이 순서

  1. 월×채널 ARPPU 를 먼저 집계.
  2. 월 안에서 RANK() → 파티션은 월.
  3. 채널 기준으로 LAG(rnk) → 파티션은 채널. 파티션 기준이 다르다.
  4. 윈도우 결과를 다시 윈도우에 넣으려면 한 단계 감싸야 한다.

정답 (MySQL)

WITH a AS (
  SELECT DATE_FORMAT(p.paid_date, '%Y-%m-01') AS mm, u.channel,
         ROUND(SUM(p.amount) / COUNT(DISTINCT p.user_id), 2) AS arppu
  FROM payments p JOIN users u ON u.user_id = p.user_id
  GROUP BY mm, u.channel
),
r AS (
  SELECT mm, channel, arppu,
         RANK() OVER (PARTITION BY mm ORDER BY arppu DESC) AS rnk
  FROM a
)
SELECT DATE_FORMAT(mm, '%Y-%m') AS month, channel, arppu, rnk,
       LAG(rnk) OVER (PARTITION BY channel ORDER BY mm)       AS prev_rnk,
       LAG(rnk) OVER (PARTITION BY channel ORDER BY mm) - rnk AS rank_change
FROM r
ORDER BY mm, rnk;

함정

이렇게 변형된다

“전월 대비 매출 순위 변동”, “주간 랭킹 변화” 전부 같은 2단 구조.

← Q9. 채널별 결제 전환과 LTVQ11. 전 유저 결제 요약 (NULL 처리) →