해결된 질문
작성
·
160
·
수정됨
0
과제별 작성 쿼리
쿼리 작성 후 느낀점
## 연습문제 1번
-- select
-- title,
-- genre
-- from advanced.array_exercises
-- cross join unnest(genres) as genre
## 연습문제 2번
-- select
-- title,
-- actor.actor,
-- actor.character,
-- from advanced.array_exercises
-- cross join unnest(actors) as actor
## 연습문제 3번
-- select
-- title,
-- actor.actor,
-- actor.character,
-- genre
-- from advanced.array_exercises
-- cross join unnest (actors) as actor
-- cross join unnest (genres) as genre
## 연습문제 4번
-- select
-- user_id,
-- event_date,
-- event_name,
-- user_pseudo_id,
-- event_param.key,
-- event_param.value,
-- event_param.value.int_value
-- from advanced.app_logs
-- cross join unnest(event_params) as event_param
-- where
-- event_date = '2022-08-01'
## 연습문제 1번
-- select
-- order_date,
-- sum(if(user_id=1, amount, 0)) as user_1,
-- sum(if(user_id=1, amount, 0)) as user_2,
-- sum(if(user_id=1, amount, 0)) as user_3,
-- from advanced.orders
-- group by
-- order_date
-- order by
-- order_date asc
## 연습문제 2번
-- 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
## 연습문제 3번
-- 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
## 앱 로그 데이터 배열 PIVOT
-- with base 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
-- where
-- event_date = '2022-08-01' and
-- event_name = 'click_cart'
-- )
-- 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 base
-- group by all
## step1 : 퍼널정의, 유저 집계 방식 정하기
## step2 : 데이터 확인
-- select
-- *,
-- 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 between '2022-08-01' and '2022-08-18'
-- limit 100
## step3 : pivot 해서 concat 하기 좋은 형태로 만들기
with base as (
select
*,
max(if(event_param.key = 'firebase_screen', event_param.value.string_value, null)) as firebase_screen,
max(if(event_param.key = 'food_id', event_param.value.int_value, null)) as food_id,
max(if(event_param.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
)
## step4 : concat해서 퍼널 컬럼 정의하기
, base2 as (
select
*,
concat(event_name, '-', firebase_screen) as event_name_with_screen
from base
)
## step5 : 퍼널별 유저수 쿼리 작성 I step_number, cnt 컬럼 생성
-- 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
-- else null
-- end as step_number,
-- count(distinct user_pseudo_id) as cnt
-- from base2
-- group by
-- 1
-- having
-- step_number is not null
## step6 : 일자별 퍼널 쿼리 작성
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
else null
end as step_number,
count(distinct user_pseudo_id) as cnt
from base2
group by all
having
step_number is not null
order by
event_date
1. '~별'이라고 해서 무조건 GROUP BY는 아니다
ARRAY 또는 STRUCT 같은 구조체 타입 컬럼을 만나기 전에는 '~별'이라는 텍스트가 있을 때 GROUP BY를 떠올렸습니다.
그러나 구조체 타입 컬럼을 다루고난 이후, 생각이 달라졌습니다.
비구조체 컬럼을 구조체 컬럼과 함께 출력할 때는 '~별'을 GROUP BY로 출력할 수 없다는 걸 알았습니다.
2. CROSS JOIN을 2개 이상 사용할 때는
CROSS JOIN을 2개 이상 입력할 때는 쉼표를 사용하지 않는다는 걸 알았습니다.
다른 구간에서 요소를 2개 이상 입력할 때는 쉼표를 사용해서 요소를 분리 했었는데, CROSS JOIN은 아니였습니다.
CROSS JOIN을 2개 이상 사용할 때 쉼표를 쓰면 다음과 같은 오류가 발생하는 걸 알았습니다 :
--> Syntax error: Unexpected keyword CROSS at [24:1]
1. 날짜 데이터와 다르게 일반 숫자데이터는 따옴표를 쓰지 않는다
EX)
if(user_id=1, amount, 0) --> O
if(user_id='1', amount, 0) --> X
+
if(user_id='2024-10-22', amount, 0) --> O
2. 컬럼명에 대시(또는 한글)를 사용할 때는 따옴표가 아닌 백틱으로 컬럼명을 감싼다
대시를 컬럼명으로 할 때는 백틱을 사용.
as 2023-05-01
--> O
as '2023-05-01' --> X
+
as 빠짝스터디
--> O
as '빠짝스터디' --> X
3. 일반 테이블을 피봇테이블로 만들 때 고려해 봐야 할 2가지
1. 행에 2개 이상 중복이 있는지 확인한다.
2. 2개 이상 중복이 있지만, 피봇테이블로 변경 했을 때 효율적인지 생각해 본다.
위 2개 조건을 모두 충족하는 컬럼을 피봇테이블 만들 때 기준 컬럼으로 삼음.
EX)
*'앱 로그 데이터 배열 PIVOT 하기' 테이블 참고
student 열
중복 있음 (A, A, A, B, B, B)
기준 열로 삼으면 → 각 학생의 모든 과목 점수를 한눈에 볼 수 있어서 효율적!
subject 열
중복 있음 (수학, 영어, 과학이 2번씩)
기준 열로 삼으면 → 과목별로 학생들의 점수를 볼 수는 있지만, 한 학생의 전체 성적을 보기는 어려움
score 열
중복이 없음.
기준 열로 삼으면 → 같은 점수끼리 모이겠지만, 효율이 떨어짐.
1. concat 할 때 따옴표 사용 주의
처음 concat 할 때 다음과 같이 입력했습니다.
concat(event_name, '-', 'firebase_screen')
'firebase_screen'라고 작성했었는데, 이렇게 하니깐 firebase_screen 내에 있는 데이터랑 concat 된 게 아니라 'firebase_screen'라는 문자 자체랑 concat이 되어서 혼란스러웠습니다.
concat 내에서는 따옴표를 쓰지 않고, 컬럼끼리 연결해야겠다는 걸 알게 됐습니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 레스님이 공유해주신 쿼리와 학습 후기를 보니, 상당히 깊이 있는 학습 과정을 거치신 것 같아 인상적입니다. 퍼널 분석과 관련하여 어려움을 겪으셨다면, 비슷한 질문과 답변이 인프런에 존재할 수 있습니다. 이에 도움이 될 수 있는 몇 가지 기존 답변을 안내드리겠습니다.
과제 쿼리 예시 및 피드백 - 쿼리 예시와 피드백이 포함된 게시물입니다. 퍼널 분석에서 피벗 테이블 적용과 관련된 여러 가지 팁을 얻을 수 있습니다.
퍼널별 유저 수 집계 문제 해결 - 퍼널 SQL 쿼리를 작성할 때 발생할 수 있는 문제들과 그 해결 방법에 대한 간단한 설명이 있습니다.
퍼널과 리텐션 분석의 구체적 방법 - 퍼널의 단계별 분석 및 리텐션 계산에 대한 구체적인 설명과 쿼리 작성 방법을 다룹니다.
이 외에도 퍼널 분석 시 유용할 수 있는 추가 자료를 소개드리면서, 이번에 학습하시면서 느끼신 점들을 실제로 더 효과적인 분석에 활용할 수 있도록 다양한 피드백을 얻어보세요.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.