프로젝트/GA4 분석

[GA4 퍼널 분석] Day3-2 (view_item → add_to_cart | New vs Returning 분석)

조성호 2026. 5. 8. 16:42

상품 조회는 했는데 왜 장바구니에는 담지 않았는가?

가설 : New vs Returning (신규 vs 재방문)

- 신규 사용자의 신뢰 부족/탐색 단계 때문인가?

 

신규 사용자(New)

  • 브랜드 신뢰 낮음
  • 가격 비교 가능성
  • 상품 정보 탐색 단계
  • 경쟁사 비교 가능성

재방문 사용자(Returning)

  • 이미 관심 있음
  • 비교 후 재방문 가능성
  • 구매 의도 더 높음

신규 사용자 전환율이 낮다면 신뢰/가격비교/상세정보 부족 가능성 높음

 

1. 사용자별 신규 여부 확인

사용자 유형 분류 테이블 생성

- first_visit 기준으로 신규/재방문 구분

WITH user_base AS (

  SELECT
    -- 사용자 고유 식별자 (익명 ID)
    user_pseudo_id,

    -- 해당 사용자가 first_visit(첫 방문) 이벤트가 있었는지 확인
    -- 있으면 신규 사용자(new)로 판단
    -- 없으면 returning으로 볼 예정
    MAX(CASE WHEN event_name = 'first_visit' THEN 1 ELSE 0 END) AS is_new_user

  -- GA4 전체 이벤트 데이터 사용
  -- first_visit 여부 확인이 목적
  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*`

  -- 사용자 단위로 묶기
  GROUP BY user_pseudo_id
)

SELECT *
FROM user_base
LIMIT 100;

 

user_pseudo_id is_new_user
1 1029692.955 1
2 1221278.918 1
3 1446815.883 1
4 1595098.642 1
5 1605268.117 0
6 1630580.703 1
7 1854363.338 1
8 1857091.554 1
9 1868974.171 1
10 1911435.758 1

 

2. 세션 단위 퍼널 테이블 생성

세션 기준 퍼널 구조화

- 세션별 view_item/add_to_cart 여부 생성

WITH user_base AS (

  SELECT
    user_pseudo_id,
    MAX(CASE WHEN event_name = 'first_visit' THEN 1 ELSE 0 END) AS is_new_user
  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*`
  GROUP BY user_pseudo_id
),

funnel AS (

  SELECT
    -- 이벤트 로그의 사용자 ID
    e.user_pseudo_id,

    -- 신규 / 재방문 사용자 구분
    CASE
      WHEN u.is_new_user = 1 THEN 'new'
      ELSE 'returning'
    END AS user_type,

    -- 세션 고유 ID 생성
    -- 사용자 + 세션ID 조합
    CONCAT(
      e.user_pseudo_id,
      '-',
      CAST((
        -- event_params 안에서 ga_session_id 추출
        SELECT value.int_value
        FROM UNNEST(e.event_params)
        WHERE key = 'ga_session_id'
      ) AS STRING)
    ) AS session_id,

    -- 해당 세션에서 상품 조회(view_item) 여부
    MAX(CASE WHEN e.event_name = 'view_item' THEN 1 ELSE 0 END) AS viewed,

    -- 해당 세션에서 장바구니(add_to_cart) 여부
    MAX(CASE WHEN e.event_name = 'add_to_cart' THEN 1 ELSE 0 END) AS added_to_cart

  -- 이벤트 로그 원본
  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*` e

  -- user_base와 결합
  -- 각 사용자에게 신규/재방문 속성 부여
  JOIN user_base u
    ON e.user_pseudo_id = u.user_pseudo_id

  -- 이번 분석에서는 상품 조회/장바구니만 필요
  WHERE e.event_name IN ('view_item', 'add_to_cart')

  -- 세션 단위 요약
  GROUP BY
    e.user_pseudo_id,
    user_type,
    session_id
)

SELECT *
FROM funnel
LIMIT 100;
user_pseudo_id user_type session_id viewed added_to_cart
1 1598553.057 new 1598553.0572388974-7293281782 1 0
2 2329559.528 new 2329559.5279215664-1928073188 1 0
3 2436820.835 new 2436820.8353025522-7147432164 1 0
4 2697787.242 new 2697787.2422183099-1489466940 1 0
5 2993057.015 new 2993057.0150726423-9212575871 1 0
6 3030394.746 returning 3030394.7459625087-5687003510 1 0
7 3041494.091 new 3041494.0908353891-9031234702 1 0
8 3369668.439 returning 3369668.4393910357-6232988511 1 0
9 3421688.089 returning 3421688.0888249264-394381861 1 0
10 3562857.614 new 3562857.6140353045-7271290581 1 0

 

-- 세션 퍼널 조합 확인
-- view만 한 세션, view 후 cart까지 간 세션 수 확인

WITH user_base AS (
  SELECT
    user_pseudo_id,

    CASE
      WHEN MAX(CASE WHEN event_name = 'first_visit' THEN 1 ELSE 0 END) = 1 THEN 'new'
      ELSE 'returning'
    END AS user_type

  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*`

  GROUP BY user_pseudo_id
),

funnel AS (
  SELECT
    e.user_pseudo_id,

    u.user_type,

    CONCAT(
      e.user_pseudo_id,
      '-',
      CAST((
        SELECT value.int_value
        FROM UNNEST(e.event_params)
        WHERE key = 'ga_session_id'
      ) AS STRING)
    ) AS session_id,

    MAX(CASE WHEN e.event_name = 'view_item' THEN 1 ELSE 0 END) AS viewed,

    MAX(CASE WHEN e.event_name = 'add_to_cart' THEN 1 ELSE 0 END) AS added_to_cart

  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*` e

  JOIN user_base u
    ON e.user_pseudo_id = u.user_pseudo_id

  WHERE e.event_name IN ('view_item', 'add_to_cart')

  GROUP BY
    e.user_pseudo_id,
    u.user_type,
    session_id
)

SELECT
  user_type,
  viewed,
  added_to_cart,
  COUNT(*) AS session_count

FROM funnel

GROUP BY
  user_type,
  viewed,
  added_to_cart

ORDER BY
  user_type,
  viewed DESC,
  added_to_cart DESC;
user_type viewed added_to_cart session_count
1 new 1 1 13400
2 new 1 0 54410
3 new 0 1 12
4 returning 1 1 1773
5 returning 1 0 7437
6 returning 0 1 3

 

3. 최종 전환율 계산

사용자 유형별 전환 성과 비교

- new/returning별 장바구니 전환율 계산

-- 신규(New) vs 재방문(Returning) 사용자별
-- view_item → add_to_cart 전환율 분석
-- 목표:
-- "신규 사용자가 상품은 보지만 장바구니 전환이 특히 낮은가?"
-- → 신뢰 부족 / 가격 비교 / 상세 정보 부족 가설 검증

WITH user_base AS (

  SELECT
    -- 사용자 고유 식별자 (익명 ID)
    user_pseudo_id,

    -- 해당 사용자가 first_visit(첫 방문) 이벤트가 있었는지 확인
    -- 있으면 신규 사용자(new)로 판단
    -- 없으면 returning으로 볼 예정
    MAX(CASE WHEN event_name = 'first_visit' THEN 1 ELSE 0 END) AS is_new_user

  -- GA4 전체 이벤트 데이터 사용
  -- first_visit 여부 확인이 목적
  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*`

  -- 사용자 단위로 묶기
  GROUP BY user_pseudo_id
),

funnel AS (

  SELECT
    -- 이벤트 로그의 사용자 ID
    e.user_pseudo_id,

    -- 신규 / 재방문 사용자 구분
    CASE
      WHEN u.is_new_user = 1 THEN 'new'
      ELSE 'returning'
    END AS user_type,

    -- 세션 고유 ID 생성
    -- 사용자 + 세션ID 조합
    CONCAT(
      e.user_pseudo_id,
      '-',
      CAST((
        -- event_params 안에서 ga_session_id 추출
        SELECT value.int_value
        FROM UNNEST(e.event_params)
        WHERE key = 'ga_session_id'
      ) AS STRING)
    ) AS session_id,

    -- 해당 세션에서 상품 조회(view_item) 여부
    MAX(CASE WHEN e.event_name = 'view_item' THEN 1 ELSE 0 END) AS viewed,

    -- 해당 세션에서 장바구니(add_to_cart) 여부
    MAX(CASE WHEN e.event_name = 'add_to_cart' THEN 1 ELSE 0 END) AS added_to_cart

  -- 이벤트 로그 원본
  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*` e

  -- user_base와 결합
  -- 각 사용자에게 신규/재방문 속성 부여
  JOIN user_base u
    ON e.user_pseudo_id = u.user_pseudo_id

  -- 이번 분석에서는 상품 조회/장바구니만 필요
  WHERE e.event_name IN ('view_item', 'add_to_cart')

  -- 세션 단위 요약
  GROUP BY
    e.user_pseudo_id,
    user_type,
    session_id
)

SELECT

  -- 신규 / 재방문별 결과
  user_type,

  -- 상품 조회를 한 세션 수
  COUNTIF(viewed = 1) AS view_sessions,

  -- 장바구니까지 간 세션 수
  COUNTIF(added_to_cart = 1) AS cart_sessions,

  -- 장바구니 전환율(%)
  -- 장바구니 세션 / 상품 조회 세션
  ROUND(
    SAFE_DIVIDE(
      COUNTIF(added_to_cart = 1),
      COUNTIF(viewed = 1)
    ) * 100,
    2
  ) AS add_to_cart_rate

FROM funnel

-- 상품 조회가 있었던 세션만 분석
WHERE viewed = 1

-- 신규 / 재방문별 집계
GROUP BY user_type

-- 전환율 낮은 순 정렬
ORDER BY add_to_cart_rate ASC;-- 신규(New) vs 재방문(Returning) 사용자별
-- view_item → add_to_cart 전환율 분석
-- 목표:
-- "신규 사용자가 상품은 보지만 장바구니 전환이 특히 낮은가?"
-- → 신뢰 부족 / 가격 비교 / 상세 정보 부족 가설 검증

WITH user_base AS (

  SELECT
    -- 사용자 고유 식별자 (익명 ID)
    user_pseudo_id,

    -- 해당 사용자가 first_visit(첫 방문) 이벤트가 있었는지 확인
    -- 있으면 신규 사용자(new)로 판단
    -- 없으면 returning으로 볼 예정
    MAX(CASE WHEN event_name = 'first_visit' THEN 1 ELSE 0 END) AS is_new_user

  -- GA4 전체 이벤트 데이터 사용
  -- first_visit 여부 확인이 목적
  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*`

  -- 사용자 단위로 묶기
  GROUP BY user_pseudo_id
),

funnel AS (

  SELECT
    -- 이벤트 로그의 사용자 ID
    e.user_pseudo_id,

    -- 신규 / 재방문 사용자 구분
    CASE
      WHEN u.is_new_user = 1 THEN 'new'
      ELSE 'returning'
    END AS user_type,

    -- 세션 고유 ID 생성
    -- 사용자 + 세션ID 조합
    CONCAT(
      e.user_pseudo_id,
      '-',
      CAST((
        -- event_params 안에서 ga_session_id 추출
        SELECT value.int_value
        FROM UNNEST(e.event_params)
        WHERE key = 'ga_session_id'
      ) AS STRING)
    ) AS session_id,

    -- 해당 세션에서 상품 조회(view_item) 여부
    MAX(CASE WHEN e.event_name = 'view_item' THEN 1 ELSE 0 END) AS viewed,

    -- 해당 세션에서 장바구니(add_to_cart) 여부
    MAX(CASE WHEN e.event_name = 'add_to_cart' THEN 1 ELSE 0 END) AS added_to_cart

  -- 이벤트 로그 원본
  FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*` e

  -- user_base와 결합
  -- 각 사용자에게 신규/재방문 속성 부여
  JOIN user_base u
    ON e.user_pseudo_id = u.user_pseudo_id

  -- 이번 분석에서는 상품 조회/장바구니만 필요
  WHERE e.event_name IN ('view_item', 'add_to_cart')

  -- 세션 단위 요약
  GROUP BY
    e.user_pseudo_id,
    user_type,
    session_id
)

SELECT

  -- 신규 / 재방문별 결과
  user_type,

  -- 상품 조회를 한 세션 수
  COUNTIF(viewed = 1) AS view_sessions,

  -- 장바구니까지 간 세션 수
  COUNTIF(added_to_cart = 1) AS cart_sessions,

  -- 장바구니 전환율(%)
  -- 장바구니 세션 / 상품 조회 세션
  ROUND(
    SAFE_DIVIDE(
      COUNTIF(added_to_cart = 1),
      COUNTIF(viewed = 1)
    ) * 100,
    2
  ) AS add_to_cart_rate

FROM funnel

-- 상품 조회가 있었던 세션만 분석
WHERE viewed = 1

-- 신규 / 재방문별 집계
GROUP BY user_type

-- 전환율 낮은 순 정렬
ORDER BY add_to_cart_rate ASC;
user_type view_sessions cart_sessions add_to_cart_rate
1 returning 9210 1773 19.25
2 new 67810 13400 19.76

 

가설

신규 사용자의 신뢰 부족/탐색 단계 때문인가?

 

결과

신규 사용자가 오히려 약간 더 높음

  • new: 19.76%
  • returning: 19.25%

해석

1. 신규 사용자의 신뢰 부족/탐색 단계가 장바구니 전환 저하의 핵심 원인이라는 가설은 강하게 지지되지 않는다

 

  • 신규 유저가 특별히 더 많이 이탈하지 않음
  • 오히려 신규도 비슷하거나 조금 더 잘 담음

2. 신규 사용자가 많다

  • 광고/SEO/외부 유입이 활발
  • 초기 상품 매력도 자체는 괜찮음

 

결론

문제는 “신규 사용자가 상품을 안 담는다”가 아니라 전체 사용자 모두 장바구니 전환율 자체가 약 20% 수준이라는 구조적 문제일 가능성 높음

- 누가 문제라기보다 상품 상세 경쟁력/가격/상품력 자체 문제 가능성 높음

 

 

신규/재방문 사용자별 장바구니 전환율 비교 결과, 신규 사용자의 전환율이 재방문 사용자와 유사하거나 소폭 높게 나타나 초기 신뢰 부족보다는 상품 경쟁력 또는 유입 채널 특성이 주요 요인일 가능성을 확인했음