A/B 테스트 그룹 집계 (상위 1% 제외)

난이도 보통 · 권장 14분 · 출력 컬럼 group_name, user_count, group_total_amount, arpu
이 문제 직접 풀어보기 →

문제

experiment_users 의 모든 참가자를 대상으로 그룹별 지표를 구하세요. group_name user_count 이상치를 뺀 유저 수 group_total_amount 이상치를 뺀 총 거래 금액 합계 arpu group_total_amount / user_count, 소수점 없이 반올림 · user_trades_summary 에 행이 없는 참가자는 거래 금액 0 으로 봅니다. · 이상치 판정은 '거래 금액 0 처리까지 끝낸 뒤' 그룹별로 합니다. PERCENT_RANK() OVER (PARTITION BY group_name ORDER BY 금액) > 0.99 인 유저를 뺍니다. · group_name 오름차순으로 정렬하세요.
정렬 group_name ASC

쉽게 설명하면

반 평균 낼 때 혼자 만점인 애를 빼고 계산. 단, 빼는 순서가 중요하다.

이 순서를 바꾸면 답이 달라진다.

①거래 없는 참가자를 0 으로 채운다
②그 상태에서 그룹별로 등수를 매긴다
③맨 위를 자른다
④남은 사람으로 평균

①을 빼고 ②를 하면 모집단이 달라져서 잘려나갈 사람도 달라진다.

이렇게 푼다

  1. 참가자 명단을 왼쪽에 두고 거래 금액을 붙이고 COALESCE(금액, 0).
  2. 그 결과 위에서 PERCENT_RANK() OVER (PARTITION BY 그룹 ORDER BY 금액).
  3. 한 번 더 감싸서 바깥에서 WHERE 등수 <= 0.99.
  4. 남은 것으로 인원·합계·평균.

이것만 피하면 된다

자세히

묻는 것 · 순서가 생명인 문제. ①0 채우기 → ②순위 매기기 → ③자르기 → ④집계. 이 순서를 바꾸면 답이 달라진다.

풀이 순서

  1. 실험 참가자 테이블을 왼쪽에 두고 거래 요약을 LEFT JOIN, COALESCE(금액, 0) 으로 0 을 채운다. 분모는 참가자 수여야 한다.
  2. 그 결과 위에서 PERCENT_RANK() OVER (PARTITION BY group_name ORDER BY amt). 0 을 채운 뒤에 순위를 매기는 것이 중요하다 — 0 인 유저도 모집단의 일부다.
  3. WHERE pr <= 0.99 로 이상치를 떨어뜨린다. 윈도우 함수는 WHERE 에서 못 쓰므로 반드시 서브쿼리/CTE 로 한 단 감싸야 한다.
  4. 남은 행으로 COUNT(*), SUM(amt), 그리고 ROUND(SUM(amt)/COUNT(*), 0).

정답 (MySQL)

WITH j AS (
  SELECT e.user_id, e.group_name,
         COALESCE(s.total_trading_amount, 0) AS amt
  FROM experiment_users e
  LEFT JOIN user_trades_summary s ON s.user_id = e.user_id
),
p AS (
  SELECT group_name, amt,
         PERCENT_RANK() OVER (PARTITION BY group_name ORDER BY amt) AS pr
  FROM j
)
SELECT group_name,
       COUNT(*) AS user_count,
       SUM(amt) AS group_total_amount,
       ROUND(SUM(amt) / COUNT(*), 0) AS arpu
FROM p
WHERE pr <= 0.99
GROUP BY group_name
ORDER BY group_name;

함정

이렇게 변형된다

“상·하위 1% 양쪽 제거”면 pr BETWEEN 0.01 AND 0.99. “중앙값 비교”면 ROW_NUMBER + COUNT() OVER 패턴. “전환율 비교”면 COUNT(DISTINCT 전환유저)/COUNT(DISTINCT 참가자) 로 분모를 참가자 전체로 둔다 (intention-to-treat).

← Q15. 유저별 최장 연속 거래일수Q17. 3일 이상 연속 상승 구간 모두 찾기 →