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

임노아님의 프로필 이미지
임노아

작성한 질문수

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

[ 인프런 빅쿼리 빠짝스터디 1주차 ] ARRAY, STRUCT 연습 문제 / PIVOT 연습 문제 / 퍼널 쿼리 연습 문제

작성

·

17

0

  1. ARRAY, STRUCT

--  array_exercises 테이블에서 각 영화(title)별로 장르(genres)를 UNNEST해서 보여주기. 

SELECT title, genre
FROM advanced.array_exercises
CROSS JOIN UNNEST(genres) as genre
-- array_exercises 테이블에서 각 영화(title)별로 배우(actor)와 배역(character)을 보여주기. 단, 배우와 배역은 별도의 컬럼으로 나와야 함.
 
SELECT 
title,
actor.actor,
actor.character
FROM `advanced.array_exercises`
CROSS JOIN UNNEST(actors) as actor
-- array_exercises 테이블에서 각 영화(title)별로 배우(actor), 배역(character), 장르(genre) 출력하기 한 행에 배우, 배역, 장르가 모두 표시되어야 된다.

SELECT 
title, 
actor.actor,
actor.character,
genre
FROM `advanced.array_exercises`
CROSS JOIN UNNEST(actors) as actor
CROSS JOIN UNNEST(genres) as genre 
-- 앱 로그 데이터 (app_logs)의 배열 풀기
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
limit 500

 

  1. 데이터 PIVOT

-- orders 테이블에서 유저(user_id)별로 주문 금액(amount)의 합계를 PIVOT하기. 날짜(order_date)를 행(Row)으로, user_id를 열(Column)으로 만들어야됨.

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 order_date
ORDER BY order_date asc;
--  orders 테이블에서 날짜(order_date)별로 유저들의 주문 금액(amount)의 합계를 PIVOT하기. user_id를 행으로, order_date를 열로 만들어야 됨.

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 ASC
-- orders 테이블에서 사용자(user_id)별, 날짜(order_date)별로  주문이 있다면 1, 없다면 0으로 피벗하기. user_id를 행으로, order_date를 열로 만들고 주문이 많아도 1로 처리.

SELECT user_id,
sum(if(order_date = '2023-05-01',1, 0)) AS `2023-05-01`,
sum(if(order_date = '2023-05-02',1, 0)) AS `2023-05-02`,
sum(if(order_date = '2023-05-03',1, 0)) AS `2023-05-03`,
sum(if(order_date = '2023-05-04',1, 0)) AS `2023-05-04`,
sum(if(order_date = '2023-05-05',1, 0)) AS `2023-05-05`
FROM advanced.orders
GROUP BY user_id 
ORDER BY user_id ASC
-- 앱 로그 데이터 배열 PIVOT 하기 ( user_id = 32888이 카트 추가하기 (click_cart)를 누를때 어떤 음식(food_id)을 담았나?)

WITH app_pivot AS (
SELECT 
user_id, 
event_date,
event_name, 
user_pseudo_id,
event_param.key AS key,
event_param.value.string_value AS string_value,
event_param.value.int_value AS int_value
FROM advanced.app_logs
CROSS JOIN UNNEST(event_params) as event_param ) 

SELECT 
user_id, 
event_date,
event_name, 
user_pseudo_id,
MAX(IF(key = 'firebase_screen', string_value,NULL)) AS `firebase_screen`,
MAX(IF(key = 'food_id',int_value,NULL)) AS `food_id`,
MAX(IF(key = 'session_id',string_value,NULL)) AS `session_id`
FROM app_pivot
WHERE user_id = 32888 AND event_name = 'click_cart'
GROUP BY user_id,event_date, event_name, user_pseudo_id
ORDER BY event_date ASC;
  1. 퍼널 분석

-- 일자별 이벤트 별 집계형태를 PIVOT 형태로 전환하기

WITH param_pivot AS (
SELECT 
event_date,
event_timestamp,
event_name, 
user_id,
user_pseudo_id,
MAX(IF(key = 'firebase_screen', event_param.value.string_value,NULL)) AS `firebase_screen`,
MAX(IF(key = 'food_id',event_param.value.int_value,NULL)) AS `food_id`,
MAX(IF(key = 'session_id',event_param.value.string_value,NULL)) AS `session_id`
FROM advanced.app_logs
CROSS JOIN UNNEST(event_params) AS event_param
WHERE event_date BETWEEN '2022-08-01' AND '2022-08-18'
GROUP BY ALL),

event_table AS (SELECT 
* EXCEPT(event_name,firebase_screen),
CONCAT(event_name,'_', firebase_screen) AS event_name_with_screen,
FROM param_pivot
WHERE event_name IN ('screen_view','click_payment')
GROUP BY all
ORDER BY event_date ASC )
,
final AS (SELECT 
event_date,
 event_name_with_screen,
(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 = 'clik_payment_cart' THEN 6 
      ELSE NULL END ) AS step_number,
COUNT( DISTINCT user_pseudo_id) AS cnt
FROM event_table
GROUP BY event_date, event_name_with_screen
HAVING step_number IS NOT NULL
ORDER BY event_date)

SELECT event_date,
SUM(IF(event_name_with_screen = 'screen_view_welcome', cnt, 0)) AS `screen_view_welcom`,
SUM(IF(event_name_with_screen = 'screen_view_home', cnt, 0)) AS `screen_view_home`,
SUM(IF(event_name_with_screen = 'screen_view_food_category', cnt, 0)) AS `screen_view_food_category`,
SUM(IF(event_name_with_screen = 'screen_view_restaurant', cnt, 0)) AS `screen_view_restaurant`,
SUM(IF(event_name_with_screen = 'screen_view_cart', cnt, 0)) AS `screen_view_cart`,
SUM(IF(event_name_with_screen = 'click_payment_cart', cnt, 0)) AS `click_payment_cart`
FROM final
GROUP BY event_date
ORDER BY event_date ASC;

답변 1

0

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

BigQuery에서 ARRAY, STRUCT, PIVOT, 그리고 퍼널 쿼리를 활용한 연습문제를 진행하고 계시네요. 복잡한 데이터 구조와 SQL 문법을 활용하여 다양한 형태로 데이터를 변형하고 시각화하는 과정은 분석 역량을 키우는데 큰 도움이 됩니다.

먼저, ARRAY와 STRUCT 데이터 타입을 사용하는 연습 문제에서는, 데이터의 복잡한 구조를 효과적으로 풀어내기 위해 UNNEST 함수를 사용하여 배열 또는 구조화된 데이터를 별도의 컬럼으로 분해하는 방법을 사용하셨습니다. 이 방법을 통해 보다 직관적으로 데이터를 조회하고 분석할 수 있습니다.

PIVOT 문제에서는, 데이터의 특정 차원(예: 날짜, 사용자 ID)을 행과 열로 변환함으로써 데이터의 다양한 관점을 제공하고 있습니다. IFSUM 함수를 조합하여 데이터를 시각화하는 방법은 SQL에서 자주 사용되는 패턴입니다.

퍼널 분석 부분에서는 이벤트 데이터의 단계별 사용자의 흐름을 분석하는 쿼리를 작성하셨군요. 기본적으로 CROSS JOIN을 통해 각 이벤트를 세부적으로 나누고, CASE WHEN 구문을 통해 단계를 정의한 후, COUNT로 유저 수를 집계하는 방식은 퍼널 분석의 기본적인 구조를 잘 반영하고 있습니다.

관련해서 유사한 질문들을 참고하시어 더 많은 인사이트를 얻으실 수 있을 것입니다:

  1. ‘퍼널별 유저 수 집계 쿼리 문제 해결’ - 퍼널 쿼리 작성 시 올바른 결과를 얻기 위해 주의해야 할 사항들을 다룹니다.
  2. ‘SQL로 퍼널 형식 데이터 피벗 하기’ - 피벗과 관련된 쿼리 작성과 데이터 변환을 수행하는 예제.

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

임노아님의 프로필 이미지
임노아

작성한 질문수

질문하기