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

jenna님의 프로필 이미지

작성한 질문수

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

3-6. 리텐션 SQL 쿼리 작성하기 : N Day Retention

리텐션 SQL 작성하기

해결된 질문

24.10.15 14:43 작성

·

30

0

쿼리 작성하다가 DISTINCT에 대해 궁금한 점이 생겨 질문 남깁니다!

  • WITH 문 base 와 first_week_data에서 DISTINCT는 중복 방지 즉, 비용 절약을 위해서 쓰는 것으로 이해했습니다.

    그렇다면 DISTINCT를 쓰지 않아도 쿼리상 문제는 없는 게 맞을까요?

  • user_count에서 DISTINCT는 유니크 유저수를 위해 꼭 사용해야하는 것으로 이해했습니다.

WITH base AS (
  SELECT 
   DISTINCT
    user_id,
    event_name,
    DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul') AS event_datetime,
    DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul')) AS event_date,
    user_pseudo_id
  FROM advanced.app_logs
)
,first_week_data AS (
  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 week_date
  FROM base
)
,first_week_diff_data AS (
  SELECT 
  *,
  DATE_DIFF(week_date,first_week,week) AS first_week_diff
  FROM first_week_data
)
,user_count AS (
SELECT 
 first_week_diff,
 COUNT(DISTINCT user_pseudo_id) AS user_cnt
FROM first_week_diff_data
GROUP BY ALL
)
,first_user_count AS (
SELECT 
 first_week_diff,
 user_cnt,
 FIRST_VALUE(user_cnt) OVER (ORDER BY first_week_diff) AS first_user_cnt
FROM user_count
)
SELECT 
 *,
 ROUND(SAFE_DIVIDE(user_cnt,first_user_cnt),2) AS rentention_ratio 
FROM first_user_count

답변 1

0

카일스쿨님의 프로필 이미지
카일스쿨
지식공유자

2024. 10. 15. 17:18

안녕하세요.

 

해당 쿼리에서 first_week_data CTE 구문에서 distinct가 없으면 여러 Row가 생기게 됩니다. first_week_data를 구할 때 유저별 일자별로 Row가 1개만 남도록 의도했다면 DISTINCT를 작성하는게 좋습니다

DISTINCT는 중복을 제거할 때 사용하는 것이고, 위 쿼리에서는 리텐션을 구하기 위함이라 DISTINCT를 쓰는게 더 좋습니다. DISTINCT를 사용하지 않아도 마지막에 user_cnt를 구할 때 DISTINCT해서 이 쿼리에선 결과 차이가 없긴 하지만, 실무에서 여러 JOIN이 있는 쿼리를 하시다가 데이터가 뻥튀기 될 수 있습니다. 이를 위해 평소부터 중복을 제거하며 쿼리를 작성하는 것을 추천드려요.

Row가 많다는 것은 이후에 쿼리의 성능에도 영향을 미치기 때문에 중복 데이터가 있다면 제거하는 것이 좋습니다

jenna님의 프로필 이미지

작성한 질문수

질문하기