inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

[인프런 빅쿼리 빠짝스터디 3주차] 리텐션 분석

137

망고맛있어

작성한 질문수 5

0

연습문제

(1) weekly retention

--1) weekly retention
WITH base AS (
  -- 날짜 데이터 전처리 
  -- DATE도 실제 날짜와 일치하지 않을 수 있으니, 다시 확인하기 
  -- DATETIME(TIMESTAMP_MICROS(timestamp데이터),'대륙/국가') 기억하고 사용하기 

  SELECT 
    DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul') AS event_datetime, 
    DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul')) AS event_date,
    event_name, 
    user_pseudo_id
  FROM `bigquery-432401.avdanced.app_logs_temp` 
)
-- 일자 간 차이 구하기 
, cal_week AS (
  SELECT
    DISTINCT 
      user_pseudo_id,
      -- 최초일(week 단위로) 구하기
      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
), cal_diff AS (
  -- 주차데이터간 차이 구하기
  SELECT
    *,
    DATE_DIFF(event_week, first_week,WEEK) AS diff_week
  FROM cal_week
), user_count AS (
  -- 주차별 user 수 구하기 
  SELECT
    diff_week,
    COUNT(distinct user_pseudo_id) as user_cnt
  FROM cal_diff
  GROUP BY diff_week
)
-- 출력
SELECT
*, 
  ROUND(SAFE_DIVIDE(user_cnt, first_week_user_cnt),2) AS retention_rate
FROM (
  SELECT
    diff_week,
    user_cnt,
    FIRST_VALUE(user_cnt) OVER(ORDER BY diff_week) AS first_week_user_cnt
  FROM user_count
)

(2) Retain User

WITH base AS (
  -- 날짜 데이터 전처리 
  -- DATE도 실제 날짜와 일치하지 않을 수 있으니, 다시 확인하기 
  -- DATETIME(TIMESTAMP_MICROS(timestamp데이터),'대륙/국가') 기억하고 사용하기 

  SELECT 
    DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul') AS event_datetime, 
    DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul')) AS event_date,
    event_name, 
    user_pseudo_id
  FROM `bigquery-432401.avdanced.app_logs_temp` 
  WHERE
    event_date BETWEEN "2022-08-01" AND "2022-11-03"
)
, cal_diff AS (
  -- 날짜데이터 간 차이 구하기
  SELECT
    *,
    DATE_DIFF("2022-11-03", event_date,DAY) AS diff_date
  FROM base
), user_type AS (

  -- user type 구하기
  -- 0. 해당없음
  -- 1. new : 첫번째 접속
  --2. current : 최근 30일내에 접속
  -- 3. resurrected : 30일 이상 활동이 없고, 최근 7일 이내 다시 접속한 사용자
  -- 4. dormant : 최근 60일 간 접속기록 없음  
  SELECT
    *,
    CASE
      -- 첫 번째 접속 => 'new'
      WHEN diff_date = FIRST_VALUE(diff_date) OVER(PARTITION BY user_pseudo_id ORDER BY event_date) THEN 'new' 
      -- 최근 30일 내에 접속한 사용자 => 'current'
      WHEN diff_date <= 30 THEN 'current'
      -- 30일 이상 활동이 없고, 최근 7일 이내 다시 접속한 사용자 => 'resurrected'
      WHEN diff_date > 30 AND diff_date <= 37 THEN 'resurrected'
      -- 60일 이상 접속하지 않은 사용자 => 'dormant'
      WHEN diff_date > 60 THEN 'dormant'
      ELSE 'none'
    END AS type
  FROM cal_diff
  GROUP BY all
  ORDER BY user_pseudo_id,diff_date
)
SELECT 
  *
FROM user_type
image.png

(3) 어떤 user가 많은가?

WITH base AS (
  -- 날짜 데이터 전처리
  SELECT 
    DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul') AS event_datetime, 
    DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul')) AS event_date,
    event_name, 
    user_pseudo_id
  FROM `bigquery-432401.avdanced.app_logs_temp` 
  WHERE
    event_date BETWEEN "2022-08-01" AND "2022-11-03"
),
cal_diff AS (
  -- 날짜데이터 간 차이 구하기
  SELECT
    *,
    DATE_DIFF("2022-11-03", event_date, DAY) AS diff_date
  FROM base
),
user_type AS (
  -- user type 구하기
  SELECT
    distinct user_pseudo_id,
    CASE
      WHEN diff_date = FIRST_VALUE(diff_date) OVER(PARTITION BY user_pseudo_id ORDER BY event_date) THEN 'new'
      WHEN diff_date <= 30 THEN 'current'
      WHEN diff_date > 30 AND diff_date <= 37 THEN 'resurrected'
      WHEN diff_date > 60 THEN 'dormant'
      ELSE 'none'
    END AS type
  FROM cal_diff
), cal_cnt AS (
  -- 각 type별 사용자 수 계산
  SELECT 
    type, 
    COUNT(user_pseudo_id) AS user_cnt
  FROM user_type
  GROUP BY type
)
SELECT
  type,
  user_cnt,
  ROUND(user_cnt * 100.0 / (SELECT COUNT(*) FROM user_type), 2) AS ratio
FROM cal_cnt
ORDER BY ratio DESC

 

image.png

(4) core event를 click_payment로 놓았을 때 Weekly retention

WITH base AS (
  SELECT 
    event_name,
    user_pseudo_id,
    DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, 
    DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_time
  FROM
  `bigquery-432401.avdanced.app_logs_temp`
  WHERE event_name = "click_payment"
), week_diff AS (
    SELECT
        *,
        DATE_DIFF(event_week, first_week, WEEK) AS diff
    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,
        COUNT(DISTINCT user_pseudo_id) AS user_cnt
    FROM week_diff
    GROUP BY diff
)


SELECT
  *,
  ROUND(SAFE_DIVIDE(user_cnt, first_week_user_cnt), 2) AS retention_rate
FROM (
  SELECT
    diff,
    user_cnt,
    FIRST_VALUE(user_cnt) OVER(ORDER BY diff ASC) AS first_week_user_cnt
  FROM user_counts
)
image.pngimage.png

 

배운점 및 느낀점

sql Google-Analytics firebase google-sheets bigquery

답변 1

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다. 망고맛있어님께서 리텐션 분석에 대해서 여러 가지 연습문제를 푸시면서 느끼신 점과 궁금한 점을 잘 공유해주셨습니다.

리텐션 분석과 사용자 타입 나누기에 대한 질문은 리텐션의 정의 및 분석 전략을 이해하는 데 도움을 주실 수 있는 다양한 답변들을 제공합니다. 비슷한 요구사항을 가진 질문에 대한 답변을 참조해보세요:

  1. 3-7 리텐션 SQL 쿼리 작성하기 연습 (Weekly, Monthly)

    • 이 답변에서는 주별 리텐션 분석을 위한 SQL 쿼리 및 이로부터 도출된 결과의 해석 방법을 이해하는 데 도움을 줄 수 있습니다. 특히, 주별 리텐션을 계산하는 쿼리 구조를 자세히 설명하고 있으므로, 이를 통해 쿼리를 더욱 최적화할 수 있을 것입니다.
  2. 리텐션 과제_연습문제 2번

    • 복잡한 리텐션 쿼리와 사용자 행동 유형에 따라 그룹을 나누는 방법에 대한 추가 정보를 제공합니다. 이를 통해 현업에서의 기준을 설정하는 방법에 대해 깊이 있는 이해를 얻을 수 있습니다.

리텐션 분석은 사용자 행동을 이해하고, 서비스 개선을 위한 중요한 인사이트를 제공합니다. 사용자 유형을 나누는 기준은 보통 사용자의 활동 빈도, 특정 이벤트 참여 여부, 그리고 재이용 가능성 등에 기반합니다. 그러므로 데이터를 분석함으로써, 더욱 효과적인 사용자 타입 분류 기준을 도출할 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏

추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

최종 과제 제출

0

82

3

BigQuery 활용편 18강 질문있습니다!

0

84

1

리텐션 공부하다가 궁금한게 생겨 질문드립니다

0

83

2

안녕하세요 강사님 코호트 쿼리 공부하다가 의문점이 생겨서 문의드립니다

0

75

2

biquery 테이블 생성 오류 이슈

0

55

2

동일하게 쿼리를 작성했는데 화면과 다른 값이 나옵니다

0

73

2

[과제] 퍼널 PIVOT 테이블 작성하기

0

67

2

array 등

0

63

2

N day 리텐션 쿼리 관련 질문

0

63

2

이동평균 계산 시 order by 기본값은 뭔가요?

0

69

2

윈도우 연습문제 1번 질문

0

65

1

user_id에 NULL이 나오는데 정상인가요?

0

72

2

3-13 리텐션 과제 제출

0

94

2

최종 과제 제출

0

130

3

weekly retention 구하기 과제

0

90

2

1-9. 피벗 쿼리 작성

0

81

2

app_logs 테이블 생성 문제

0

73

2

Weekly Retention 구하기 완성하였습니다.

0

77

2

[과제] 퍼널 쿼리(피벗테이블 적용) 작성 완료

0

106

2

3-7 Weekly, Monthly Retention 쿼리 작성

0

92

2

정성 데이터 분석 방법 문의

0

165

1

최종 과제 제출

0

108

3

1-6 예시 문제 풀이

0

69

2

최종과제 제출

0

145

2