inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

[빠짝스터디 1주차 과제] ARRAY, STRUCT / PIVOT / 퍼널 연습 문제

80

soojeong

작성한 질문수 3

0

1. ARRAY, STRUCT


-- 1. array_exercises 테이블에서 각 영화(title)별로 장르(genres)를 UNNEST해서 보여주세요.
-- genres 꺼내기
SELECT
  title
  , genre
FROM `advanced.array_exercises`
  CROSS JOIN UNNEST(genres) AS genre

-- 2. array_exercises 테이블에서 각 영화(title)별로 배우(actor)와 배역(character)을 보여주세요.
-- arrary 안의 struct 영화/배우 꺼내기
SELECT
  title
  , ac.actor
  , ac.character
FROM `advanced.array_exercises`
  CROSS JOIN UNNEST(actors) AS ac -- actor.actor도 가능

-- 3. array_exercises 테이블에서 각 영화(title)별로 배우(actor)와 배역(character), 장르(genre) 출력
-- actors, genres 각각 꺼내기 (2번 조인)
SELECT
-- title, actor, character, genre
  title
  , ac.actor
  , ac.character
  , genre
FROM `advanced.array_exercises`
  CROSS JOIN UNNEST(actors) AS ac
  CROSS JOIN UNNEST(genres) AS genre

-- 4. 앱로그 데이터(app_logs)의 배열을 풀어주세요.
-- event_params 꺼내기
SELECT
  user_id
  , event_date
  , event_name
  , user_pseudo_id
  , event_param.key
  , event_param.value.string_value
  , event_param.value.int_value
FROM `advanced.app_logs`
 CROSS JOIN UNNEST(event_params) AS event_param
-- WHERE event_date = '2022-08-01' -- test

 

2. PIVOT


-- 1. orders 테이블에서 유저(user_id)별로 주문 금액(amount)의 합계를 PIOVT해주세요.
-- 날짜(order_date)를 행, user_id를 열, sum(amount)
SELECT
  order_date
  , SUM(IF(user_id = 1, amount, 0)) AS user_1
  , SUM(IF(user_id = 2, amount, 0)) AS user_2
  , SUM(IF(user_id = 3, amount, 0)) AS user_3
FROM `advanced.orders`
GROUP BY 1
ORDER BY 1

-- 2. orders 테이블에서 날짜(order_date)별로 유저들의 주문 금액(amount) 합계를 PIVOT
-- user_id 행, order_date 열, sum(주문 금액), '-' 포함 날짜 별칭은 backtick(``) 활용
SELECT
  user_id
  , SUM(IF(order_date = '2023-05-01', amount, 0)) AS `2023-05-01`
  , SUM(IF(order_date = '2023-05-02', amount, 0)) AS `2023-05-02`
  , SUM(IF(order_date = '2023-05-03', amount, 0)) AS `2023-05-03`
  , SUM(IF(order_date = '2023-05-04', amount, 0)) AS `2023-05-04`
  , SUM(IF(order_date = '2023-05-05', amount, 0)) AS `2023-05-05`
FROM `advanced.orders`
GROUP BY user_id
ORDER BY user_id

-- 3. orders 테이블에서 사용자별 날짜별로 주문이 있다면 1, 없으면 0으로 PIOVT
-- user_id 행, order_date 열, if(날짜, 1, 0)
SELECT
  user_id
  , MAX(IF(order_date = '2023-05-01', 1, 0)) AS `2023-05-01`
  , MAX(IF(order_date = '2023-05-02', 1, 0)) AS `2023-05-02`
  , MAX(IF(order_date = '2023-05-03', 1, 0)) AS `2023-05-03`
  , MAX(IF(order_date = '2023-05-04', 1, 0)) AS `2023-05-04`
  , MAX(IF(order_date = '2023-05-05', 1, 0)) AS `2023-05-05`
FROM `advanced.orders`
GROUP BY user_id
ORDER BY user_id

 

3. 퍼널


3-1. 퍼널별 유저 수

-- 1. 퍼널별 유저 수 : 2022-08-01 ~ 2022-08-18, 오픈 퍼널, COUNT(DISTINCT user_pseudo_id)

WITH funnels AS (
-- 조건/컬럼 필터링, event_params UNNEST, event name + screen 문자열 컬럼 병합
SELECT
  CONCAT(event_name, '-', event_param.value.string_value) AS event_name_with_screen
  , COUNT(DISTINCT user_pseudo_id) AS cnt
FROM `advanced.app_logs`
  CROSS JOIN UNNEST(event_params) AS event_param
WHERE event_date BETWEEN '2022-08-01' AND '2022-08-18'
AND event_name IN ('screen_view', 'click_payment')
AND event_param.key = 'firebase_screen'
AND event_param.value.string_value NOT IN ('food_detail', 'search', 'search_result')
GROUP BY ALL
)

SELECT 
  event_name_with_screen
  -- step_number 생성
  , (CASE
      WHEN event_name_with_screen = 'screen_view-welcome' THEN 1
      WHEN event_name_with_screen = 'screen_view-home' THEN 2
      WHEN event_name_with_screen = 'screen_view-food_category' THEN 3
      WHEN event_name_with_screen = 'screen_view-restaurant' THEN 4
      WHEN event_name_with_screen = 'screen_view-cart' THEN 5
      WHEN event_name_with_screen = 'click_payment-cart' THEN 6
    END
    ) AS step_number
  , cnt
FROM funnels
ORDER BY step_number

3-2. 퍼널별 유저 수(일자별)

-- 2. 퍼널별 유저 수(일자별) : 2022-08-01 ~ 2022-08-18, 오픈 퍼널, COUNT(DISTINCT user_pseudo_id)

WITH funnels AS (
-- 조건/컬럼 필터링, event_params UNNEST, event name + screen 문자열 컬럼 병합
SELECT
  -- 일자별
  event_date
  , CONCAT(event_name, '-', event_param.value.string_value) AS event_name_with_screen
  , COUNT(DISTINCT user_pseudo_id) AS cnt
FROM `advanced.app_logs`
  CROSS JOIN UNNEST(event_params) AS event_param
WHERE event_date BETWEEN '2022-08-01' AND '2022-08-18'
AND event_name IN ('screen_view', 'click_payment')
AND event_param.key = 'firebase_screen'
AND event_param.value.string_value NOT IN ('food_detail', 'search', 'search_result')
GROUP BY ALL
)

SELECT 
  event_date
  , event_name_with_screen
  -- step_number 생성
  , (CASE
      WHEN event_name_with_screen = 'screen_view-welcome' THEN 1
      WHEN event_name_with_screen = 'screen_view-home' THEN 2
      WHEN event_name_with_screen = 'screen_view-food_category' THEN 3
      WHEN event_name_with_screen = 'screen_view-restaurant' THEN 4
      WHEN event_name_with_screen = 'screen_view-cart' THEN 5
      WHEN event_name_with_screen = 'click_payment-cart' THEN 6
    END
    ) AS step_number
  , cnt
FROM funnels
ORDER BY event_date, step_number -- 정렬 변경

 

3-3. 퍼널별 유저 수(일자별 PIVOT)

-- 3. 퍼널별 유저 수(일자별) 집계 PIVOT

WITH funnels AS (
-- 조건/컬럼 필터링, event_params UNNEST, event name + screen 문자열 컬럼 병합
SELECT
  -- 일자별
  event_date
  , CONCAT(event_name, '-', event_param.value.string_value) AS event_name_with_screen
  , COUNT(DISTINCT user_pseudo_id) AS cnt
FROM `advanced.app_logs`
  CROSS JOIN UNNEST(event_params) AS event_param
WHERE event_date BETWEEN '2022-08-01' AND '2022-08-18'
AND event_name IN ('screen_view', 'click_payment')
AND event_param.key = 'firebase_screen'
AND event_param.value.string_value NOT IN ('food_detail', 'search', 'search_result')
GROUP BY ALL
)

SELECT 
  event_date
  -- event PIVOT
  , 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 funnels
GROUP BY ALL
ORDER BY event_date

 

sql Google-Analytics firebase google-sheets bigquery

답변 1

0

인프런 AI 인턴

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

BigQuery에서 ARRAY, STRUCT 및 PIVOT 기능을 사용하여 다양한 데이터 분석 쿼리를 구성한 점, 특히 퍼널 분석을 통해 데이터를 시각화하는 접근 방식은 매우 유익한 학습 과정이 될 것입니다. 같은 주제에 대한 질문과 답변이 진행된 경우가 있어 몇 가지 유사한 답변을 소개해 드립니다:

  1. 구글 스프레드시트 사용 시 데이터 로그 설계에 대한 질문: SQL에서 다양한 파라미터를 어떻게 설계하고 사용해야 하는지에 대한 내용을 다루고 있습니다. 퍼널 분석에서도 파라미터의 사용은 중요하므로 도움이 될 수 있습니다.

  2. 퍼널 SQL 쿼리 작성하기 - 오류 해결 사례: 퍼널 쿼리 작성 시 발생할 수 있는 오류들과 그 해결 방안에 대한 내용을 다룹니다. 특히, PIVOT를 활용한 데이터를 시각화하는 방법에 대해 상세히 설명하고 있습니다.

위 링크의 게시글들은 BigQuery를 이용한 데이터 처리와 시각화 작업에 있어 기초적인 이해를 돕고 존재할 수 있는 오류를 피할 방법을 안내하고 있습니다. 이를 통해 실전에서의 분석 작업에 더 자신감을 가질 수 있을 것입니다.

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

최종 과제 제출

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