강의

멘토링

로드맵

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

peahen23님의 프로필 이미지
peahen23

작성한 질문수

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

작성

·

58

·

수정됨

0

ARRAY, STRUCT
1) array_exercises 테이블에서 각 영화(title)별로 장르(genres)를 UNNEST해서 보여주세요.

SELECT 
  title, 
  genre 
FROM advanced.array_exercises
CROSS JOIN UNNEST(genres) as genre

2) array_exercises 테이블에서 각 영화(title)별로 배우(actor)와 배역(character)을 보여주세요. 배우와 배역은 별도의 컬럼으로 나와야 합니다.

SELECT 
  title, 
  actor.actor, 
  actor.character
FROM advanced.array_exercises
CROSS JOIN UNNEST(actors) as actor

3) array_exercises 테이블에서 각 영화(title)별로 배우(actor), 배역(character), 장르 (genre)를 출력하세요. 한 Row에 배우, 배역, 장르가 모두 표시되어야 합니다.

SELECT  
  title,
  actor.actor as actor,
  actor.character as character,
  genre
FROM advanced.array_exercises
CROSS JOIN UNNEST(genres) as genre
CROSS JOIN UNNEST(actors) as actor
ORDER BY 1, 2 desc

4) 앱 로그 데이터(app_logs)의 배열을 풀어주세요.

SELECT
  user_id,
  event_date,
  event_name,
  user_pseudo_id,  
  evnent_parm.key AS key,
  evnent_parm.value.string_value AS string_value,
  evnent_parm.value.int_value AS int_value,
FROM advanced.app_logs, UNNEST(event_params) AS evnent_parm

 

PIVOT

1) 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;

2) orders 테이블에서 날짜(order_date)별로 유저들의 주문 금액(amount)의 합계를 PIVOT 해주세요. user_id를 행(Row)으로, order_date를 열(Column)으로 만들어야 합니다.

SELECT
  user_id,
  COALESCE(SUM(IF(order_date = '2023-05-01', amount, null)),0) AS `2023-05-01`,
  COALESCE(SUM(IF(order_date = '2023-05-02', amount, null)),0) AS `2023-05-02`,
  COALESCE(SUM(IF(order_date = '2023-05-03', amount, null)),0) AS `2023-05-03`,
  COALESCE(SUM(IF(order_date = '2023-05-04', amount, null)),0) AS `2023-05-04`,
  COALESCE(SUM(IF(order_date = '2023-05-05', amount, null)),0) AS `2023-05-05`,
FROM advanced.orders
GROUP BY user_id
ORDER BY user_id;

3) orders 테이블에서 사용자(user_id)별, 날짜(order_date)별로 주문이 있다면 1, 없다면 0으로 PIVOT 해주세요. user_id를 행(Row)으로, order_date를 열(Column)로 만들고 주문을 많이 해도 1로 처리합니다.

SELECT
  user_id,
  MAX(IF(order_date = '2023-05-01' AND order_id is not null, 1, 0)) AS `2023-05-01`,
  MAX(IF(order_date = '2023-05-02' AND order_id is not null, 1, 0)) AS `2023-05-02`,
  MAX(IF(order_date = '2023-05-03' AND order_id is not null, 1, 0)) AS `2023-05-03`,
  MAX(IF(order_date = '2023-05-04' AND order_id is not null, 1, 0)) AS `2023-05-04`,
  MAX(IF(order_date = '2023-05-05' AND order_id is not null, 1, 0)) AS `2023-05-05`,

FROM advanced.orders

GROUP BY user_id
ORDER BY user_id;

 

퍼널 분석

1) 퍼널 별 유저 수 집계
데이터 : 2022-08-01 ~ 2022-08-18

WITH funnel_data_raw AS (
SELECT  
  event_date,
  event_timestamp,
  event_name,
  user_id,
  user_pseudo_id,
  MAX(IF(pr.key = 'firebase_screen', pr.value.string_value, null)) AS screen_name,
  CONCAT(event_name, '-', MAX(IF(pr.key = 'firebase_screen', pr.value.string_value, null))) AS event_name_with_screen
FROM advanced.app_logs, UNNEST(event_params) AS pr
WHERE event_date BETWEEN '2022-08-01' AND '2022-08-18'
GROUP BY 1,2,3,4,5
)
SELECT
  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 = 'click_payment-cart' THEN 6 END AS step_number,
  COUNT(DISTINCT user_pseudo_id) AS cnt
FROM funnel_data_raw
WHERE event_name IN ('screen_view', 'click_payment')
  AND screen_name IN ('welcome', 'home', 'food_category', 'restaurant', 'cart')
GROUP BY 1,2
ORDER BY 2
;

2) 퍼널 별 유저 수 집계 (일자별)

WITH funnel_data_raw AS (
SELECT  
  event_date,
  event_timestamp,
  event_name,
  user_id,
  user_pseudo_id,
  MAX(IF(pr.key = 'firebase_screen', pr.value.string_value, null)) AS screen_name,
  CONCAT(event_name, '-', MAX(IF(pr.key = 'firebase_screen', pr.value.string_value, null))) AS event_name_with_screen
FROM advanced.app_logs, UNNEST(event_params) AS pr
WHERE event_date BETWEEN '2022-08-01' AND '2022-08-18'
GROUP BY 1,2,3,4,5
)
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 = 'click_payment-cart' THEN 6 END AS step_number,
  COUNT(DISTINCT user_pseudo_id) AS cnt
FROM funnel_data_raw
WHERE event_name IN ('screen_view', 'click_payment')
  AND screen_name IN ('welcome', 'home', 'food_category', 'restaurant', 'cart')
GROUP BY 1,2,3
ORDER BY 1,3
;

3) 집계한 데이터를 PIVOT

-- 연구 및 추가적 작업 필요

 

배운점

  • 대용량의 복잡한 데이터를 의도에 따라 구조화 및 시각화하는 기초 지식을 습득함.

     

  • 과업이 복잡해지면 쿼리가 깔끔하게 정리가 되지 않거나 스텝이 꼬이는 등의 어려움을 겪기도 함.

  • 각 연습문제에 대해 '왜이 쿼리를 실행하는 것이며, 그 결과값을 통해 어떤 추가적인 Action을 취할 수 있는가' 실무 관점으로 고민해보는 계기가 되었음.

답변 1

0

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

peahen23님이 질문에 올려주신 SQL 쿼리는 배열 및 구조형 데이터 처리, PIVOT 기능 사용, 그리고 퍼널 분석에 대한 예제입니다. 여기에 대해서 몇 가지 추가적인 설명을 드릴게요.

ARRAY와 STRUCT 처리
1) 배열을 UNNEST한 후, 각 영화의 장르를 표시합니다. UNNEST는 배열 형식을 풀어서 각각의 요소로 나열합니다.
2) 각 영화의 배우와 배역을 별도의 컬럼으로 했습니다. 배열에 포함된 STRUCT 데이터는 UNNEST 후 필요한 필드를 선택할 수 있습니다.
3) 배우와 배역, 장르를 모두 출력하기 위해 UNNEST를 두 번 사용하여 데이터를 조인했습니다.

PIVOT 기능
1) 첫 번째와 두 번째 PIVOT 예제는 특정 필드의 값을 기준으로 새로운 열을 생성하여 데이터를 회전합니다. 주어진 상황에 따라 필요한 ID나 날짜를 기준으로 값을 집계합니다.
2) 세 번째 PIVOT 예제에서는 사용자의 주문 여부를 0과 1로 표시하며, 여러 번 주문해도 1로 결과를 설정합니다.

퍼널 분석
1) 주어진 시간 범위 내의 퍼널 이벤트를 단계별로 집계하여 사용자 수를 세는 쿼리입니다.
2) 첫 번째 쿼리는 전체 기간 동안의 데이터를 집계하고, 두 번째 쿼리는 날짜별로 세분화한 결과를 보여줍니다. CASE 문을 통해 이벤트의 단계를 정의하였습니다.

마지막으로, aggregation한 데이터를 PIVOT 하는 부분은 추가적인 연구와 코드 작성이 필요하다고 합니다. 쿼리를 사용하는 목적과 실무에서 활용될 수 있는 결과에 대해 고민해보셨다는 점에서 학습 효과가 크셨을 것 같습니다.

궁금하신 점이 더 있으시다면 언제든지 질문 주시기 바랍니다. 감사합니다.

peahen23님의 프로필 이미지
peahen23

작성한 질문수

질문하기