인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

뿌뿌님의 프로필 이미지

작성한 질문수

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

1-9. 퍼널 SQL 쿼리 작성하기

[1-9. 퍼널 SQL 쿼리 작성하기] 집계데이터 pivot쿼리

해결된 질문

작성

·

125

·

수정됨

0

안녕하세요 카일스쿨님:)

강의 마지막에 선택과제(?)로 주신 집계데이터 pivot쿼리 작성해봤습니다.

쿼리를 작성하면서, 지금은 피봇할 컬럼이 많지 않아서 하나하나 피봇해주는 것으로 진행했는데 이게 최선일지가 의문이 들어서요,
피봇하는 컬럼 조건이 다를 뿐 과정은 동일해서 공통으로 적용할 수 있는 방법이 있을 것 같은데 제가 잘못 이해하고 있는 것인지, 아니면 피봇을 항상 이런식으로 진행해야 하는 것인지도 같이 질문드립니다.

감사합니다:)

 

with base as (
  select event_date
    ,event_timestamp
    ,event_name
    ,user_id
    ,user_pseudo_id
    ,max(if(param.key = 'firebase_screen',param.value.string_value,null)) as `firebase_screen`
    ,max(if(param.key = 'food_id',param.value.int_value,null)) as `food_id`
    ,max(if(param.key = 'session_id',param.value.string_value,null)) as `session_id` 
  from advanced.app_logs , unnest(event_params) as param
  where 1=1
  and event_name in ('screen_view','click_payment')
  and event_date >= '2022-08-01' 
  and event_date <= '2022-08-18'
  group by all 
  order by 1
)
, before_pivot as (
  select event_date
    ,concat(event_name,'-',firebase_screen) as `event_name_with_screen`
    ,case when event_name = 'screen_view' and firebase_screen = 'welcome' then 1 
        when event_name = 'screen_view' and firebase_screen = 'home' then 2
        when event_name = 'screen_view' and firebase_screen = 'food_category' then 3 
        when event_name = 'screen_view' and firebase_screen = 'restaurant' then 4 
        when event_name = 'screen_view' and firebase_screen = 'cart' then 5 
        when event_name = 'click_payment' and firebase_screen = 'cart' then 6
        end as `step_number`
    ,count(*) as cnt
  from base
  where 1=1
  group by 1,2,3
  having step_number is not null
)

select event_date
  ,max(if (event_name_with_screen = 'screen_view-welcome',cnt,null)) as `screen_view-welcome`
  ,max(if (event_name_with_screen = 'screen_view-home',cnt,null)) as `screen_view-home`
  ,max(if (event_name_with_screen = 'screen_view-food_category',cnt,null)) as `screen_view-food_category`
  ,max(if (event_name_with_screen = 'screen_view-restaurant',cnt,null)) as `screen_view-restaurant`
  ,max(if (event_name_with_screen = 'screen_view-cart',cnt,null)) as `screen_view-cart`
  ,max(if (event_name_with_screen = 'click_payment-cart',cnt,null)) as `click_payment-cart`
from before_pivot
group by all
order by 1

답변 2

1

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

뿌뿌님 안녕하세요! 잘 학습해주고 계시네요. 그런 생각의 흐름 너무 좋습니다!

4-3. BigQuery의 절차적 언어 파트를 학습하시면 동적으로 피벗하는 쿼리를 짜는 힌트를 얻을 수 있을거에요. 다만 처음 해보실 땐 좀 어려워보일 수 있어요.

동적으로 피벗하는 것은 예전에 아래 글에 정리해두었으니 4-3 강의 들으시고 보시면 좋을 것 같아요

https://zzsza.github.io/gcp/2021/05/16/bigquery-pivot/

뿌뿌님의 프로필 이미지
뿌뿌
질문자

감사합니다:) 설명을 너무 잘해주셔서 열심히 학습하는데 도움이 많이 되고 있습니다 ㅎㅎ 강의 만들어주셔서 감사드려요 100%까지 달려보겠습니다:)

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. 뿌뿌님.

질문자님이 질문하신 피벗 테이블의 작성법에 대해서 설명드리겠습니다. 피벗 테이블은 데이터의 특정 값들을 기준으로 열(column)을 재구성하여 요약하기 위한 유용한 기법입니다. 현재 사용하고 있는 MAX(IF(...)) 구문을 사용한 피벗은 꽤 일반적인 방식입니다. 이 방법이 직관적이고 강력하지만, 피벗할 컬럼이 많아졌다던가, 더 동적인 처리가 필요할 때는 번거로울 수 있습니다.

대체적으로 다음과 같은 방법을 고려해볼 수 있습니다:

  1. DYNAMIC SQL: BigQuery에서는 동적 SQL을 직접 생성하는 것이 약간 제한적이긴 하지만, 외부의 스크립트를 사용하여 동적으로 SQL을 구성한 후 실행할 수 있습니다. 이를 통해 피벗할 컬럼이 불확정적이거나 매번 변하는 경우에도 유연하게 대처할 수 있습니다.

  2. 비교 연산의 통일성: event_name_with_screen의 피벗을 다룰 때마다 비교 문을 작성하게 되는데, 만약 피벗할 값들이 지속적이라면 테이블로 관리하여 SQL을 생성하는 방식으로도 관리할 수 있습니다.

  3. ARRAY 및 STRUCT 사용: 피벗의 대안으로 데이터를 원하는 구조로 배열이나 구조체로 재구성하여 처리하는 방식도 고려할 수 있습니다. 여러 컬럼이 아닌 한 컬럼의 복합구조로 데이터를 유지할 수 있습니다.

현재 코드에서 사용하고 있는 MAX(IF(...))를 사용하는 방법은 매우 강력하고 범용성이 높습니다. 특히 집계 데이터 피벗에서는 유용하며, 새로운 컬럼이 추가되거나 조건이 변경되더라도 쉽게 다른 형식으로 변환할 수 있어 익숙해진다면 다른 상황에도 활용도가 높습니다.

관련된 질문 및 문제가 다루어진 사이트를 공유드립니다:

  • 퍼널 쿼리 작성에 대한 Tip

    • 다른 사용자가 퍼널 분석 쿼리를 작성할 때 가장 자주 마주치는 문제와 그 해결 방법들을 다루고 있어 매우 유용할 수 있습니다.

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

뿌뿌님의 프로필 이미지

작성한 질문수

질문하기