1. Weekly retention을 구하는 쿼리를 구하기.

image.png

	# Weekly Retenttion 쿼리 구하기.
	
	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)
	    
	# 리텐션을 구하기 위한 유저의 event_week, first_week, diff_week 구하기.
	, first_week_and_diff AS (
	      SELECT
	      *,
	      DATE_DIFF(event_week,first_week,week) AS diff_week
	      FROM
	          ( SELECT 
	              DISTINCT
	              user_pseudo_id,
	              DATE_TRUNC(event_date, WEEK(MONDAY)) AS event_week,
	              DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id),WEEK(MONDAY)) AS first_week 
	            FROM base ) )
	# 유저별 event_week, first_week, diff_week 수.
	, user_counts AS ( 
	    SELECT
	      diff_week,
	      COUNT(DISTINCT user_pseudo_id) AS user_cnt
	    FROM first_week_and_diff
	    GROUP BY ALL ) 
	
	# Weekly retention의 수와 비율.
	SELECT
	  diff_week,
	  user_cnt,
	  ROUND(SAFE_DIVIDE(user_cnt,first_week_user_cnt), 3) AS retention_rate
	FROM (
	    SELECT
	    diff_week,
	    user_cnt,
	    FIRST_VALUE(user_cnt) OVER(ORDER BY diff_week ASC) AS first_week_user_cnt
	    FROM user_counts)
	ORDER BY 1 

2. Retain User를 User + Current + Resurrected + Document User로 나누기.

1) 유저 그룹 분류

# 2. Retain User를 User + Current + Resurrected + Document 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) = 2 THEN 'Current'
      WHEN DATE_DIFF(event_week, pre_active_week, WEEK) > 2 THEN 'Resurrected'
      ELSE 'Document '
    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 ; 

image.png

image.png

image.png

3. 주어진 데이터에서 어떤 사람들이 리텐션이 높은지.


  1. New : 2022.10.09일 이후로 지속 리텐션이 낮아지고 있음.
  2. Current : 지속적으로 상승하다가, 22.10.23 이후로 400~600명 대로 현상 유지 하고 있음.