인프런 커뮤니티 질문&답변

김희은님의 프로필 이미지
김희은

작성한 질문수

BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)

[빠짝스터디 3주차 과제] 리텐션 과제

작성

·

22

·

수정됨

0

  1. Weekly Retention 구하기

# Weekly Retention을 구하는 쿼리

WITH base AS (
  SELECT
    DISTINCT
      user_id,
      user_pseudo_id,
      event_name,
      DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date,
      DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime
  FROM advanced.app_logs
  WHERE
    event_date BETWEEN "2022-08-01" AND "2022-11-03"
# 유저의 event_week, firts_week, diff_week 구하기
), first_week_and_diff AS (
  SELECT
    *,
    -- DATE_DIFF(event_date, first_date, DAY) AS diff_of_day
    DATE_DIFF(event_week, first_week, WEEK) AS diff_of_week
  FROM (
    SELECT
      # 일자별로 중복 제거
      DISTINCT 
        user_pseudo_id,
        -- DATE_TRUNC
        DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week,
        DATE_TRUNC(event_date, WEEK(MONDAY)) AS event_week
    FROM base
  )
# 유저별 event_week, first_week, diff_week 수 
), user_counts AS (
  SELECT
  diff_of_week,
  COUNT(DISTINCT user_pseudo_id) AS user_cnt
  FROM first_week_and_diff
  GROUP BY diff_of_week
)


# Weekly retention의 수와 비율
SELECT
  *,
  ROUND(SAFE_DIVIDE(user_cnt, first_week_user_cnt), 2) AS retention_rate
FROM (
  SELECT
    diff_of_week,
    user_cnt,
    FIRST_VALUE(user_cnt) OVER(ORDER BY diff_of_week ASC) AS first_week_user_cnt
  FROM user_counts
)

 

2. Retention User를 New +Current +Resurrected + Dormant User로 나누는 쿼리를 작성하기

WITH base AS ( 
    SELECT
    DISTINCT
      user_id,
      user_pseudo_id,
      event_name,
      DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul') AS event_datetime,
      DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul')) AS event_date,
    FROM advanced.app_logs)
, weekly_user_active AS (
    SELECT 
      user_pseudo_id,
      DATE_TRUNC(event_date, WEEK) AS event_week,
      MIN(DATE_TRUNC(event_date, WEEK)) OVER (PARTITION BY user_pseudo_id) AS first_active_week,
      LAG(DATE_TRUNC(event_date, WEEK)) OVER (PARTITION BY user_pseudo_id ORDER BY DATE_TRUNC(event_date, WEEK)) AS pre_active_week
      FROM base
)

, user_group AS (
  SELECT
    user_pseudo_id,
    event_week,
    DATE_DIFF(event_week, pre_active_week, WEEK(MONDAY)) AS diff_prior_week, 
    DATE_DIFF(event_week, first_active_week, WEEK(MONDAY)) AS diff_first_week,
    CASE 
      WHEN event_week = first_active_week THEN 'NEW' # 처음 사용한 유저
      WHEN DATE_DIFF(event_week, pre_active_week, WEEK) = 1 THEN 'Current' # 1주 안에 사용한 유저
      WHEN DATE_DIFF(event_week, pre_active_week, WEEK) > 1 THEN 'Resurrected' # 
      ELSE 'Dormant '
    END AS user_seg # 유저분류값
    FROM weekly_user_active
)

SELECT  
  event_week,
  user_seg,
  COUNT(DISTINCT user_pseudo_id) AS user_cnt,
FROM user_group
GROUP BY ALL
ORDER BY 1 ; 

 

  1. 어떤 사람들이 리텐션이 높은지 찾아보기

     

    image.png
  • NEW(신규유저) : 신규 유저 10월 이후 하락

  • Current (활성화 유저) : 12월까지 상승세를 보이다가 1월에 다시 하락

  • Resurrected (복귀 유저) : 지속 상승

  • Dormant User (휴면 유저) : 지속 상승

???: 왜 휴면유저와 복귀유저의 사용 비율이 비슷하게 나오는걸까..? 그래도 그나마 복귀유저가 리텐션이 더 높음

 

  1. Core Event를 "click_payment"라고 설정하고 Weekly Retention을 구하기

WITH base AS (
  SELECT
    DISTINCT
      user_id,
      user_pseudo_id,
      event_name,
      DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date,
      DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime
  FROM advanced.app_logs
  WHERE
    event_date BETWEEN "2022-08-01" AND "2022-11-03"
    AND event_name = 'click_payment'  -- Core Event 필터링
), 

first_week_and_diff AS (
  SELECT
    *,
    DATE_DIFF(event_week, first_week, WEEK) AS diff_of_week
  FROM (
    SELECT
      DISTINCT 
        user_pseudo_id,
        DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week,
        DATE_TRUNC(event_date, WEEK(MONDAY)) AS event_week
    FROM base
  )
),

user_counts AS (
  SELECT
    diff_of_week,
    COUNT(DISTINCT user_pseudo_id) AS user_cnt
  FROM first_week_and_diff
  GROUP BY diff_of_week
)

SELECT
  diff_of_week AS week,
  user_cnt,
  FIRST_VALUE(user_cnt) OVER(ORDER BY diff_of_week ASC) AS first_week_user_cnt,
  ROUND(SAFE_DIVIDE(user_cnt, FIRST_VALUE(user_cnt) OVER(ORDER BY diff_of_week ASC)) * 100, 2) AS retention_rate
FROM user_counts
ORDER BY diff_of_week

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다. 김희은님께서 작성하신 SQL 쿼리를 통한 리텐션 분석에 대한 질문에 답변드리겠습니다.

  1. Weekly Retention 구하기

작성하신 쿼리는 주차별 리텐션을 구하는 데 잘 구조화되어 있습니다. 주차별로 첫 주차의 사용자 수 대비 현재 주차 사용자 수의 비율을 계산하여 리텐션을 측정하고 있습니다.

관련하여 아래의 예제 답변을 참고하시면 도움이 될 것 같습니다: 리텐션 쿼리 작성 방법. 이 예제에서는 리텐션을 계산하는 동안 발생할 수 있는 여러 상황들을 다루고 있습니다.

  1. 사용자 분류 쿼리 작성하기

사용자 그룹(신규, 활성, 복귀, 휴면)으로 분류하는 로직도 잘 작성하셨습니다. 주차별로 사용자의 활동을 추적하여 그룹화하는 과정이 적절히 처리되어 있습니다. 다만, DocumentDormant로 수정되어야 할 것 같습니다.

  1. 유저 리텐션에 대한 인사이트

제공하신 그래프를 보면, 각각의 사용자 유형에 대한 시간이 흐르면서의 변화를 확인할 수 있습니다. 여러 사용자 유형 중, 복귀 유저가 상대적으로 높은 리텐션을 보이는 것은 흥미로운 관점입니다. 이들의 활동 증가 원인을 파악한다면 비즈니스 전략에 도움이 될 것입니다.

추가적으로, 사용자 분류에 대한 유사한 설명과 해결책을 제공하는 리텐션 및 사용자 세분화를 참고해 보실 수 있습니다.

마지막으로, Core Event를 기반으로 하는 리텐션 분석의 예시는 지식공유자님의 예제와 답변을 통해 얻을 수 있습니다. 궁금한 부분은 계속 질문해 주세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

김희은님의 프로필 이미지
김희은

작성한 질문수

질문하기