inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

[빠짝스터디 2주차 과제] 윈도우 함수, FRAME 설정, QUALIFY

95

지용

작성한 질문수 3

0

2-4. 윈도우 함수 탐색 함수 연습 문제

select 
  *,
  lead(visit_month) over (partition by user_id order by visit_month) as next_visit_month,
  lead(visit_month, 2) over (partition by user_id order by visit_month) as next_visit_month2  
from advanced.analytics_function_01
; 

결과

image.png
select 
  *,
  lead(visit_month, 1) over (partition by user_id order by visit_month) as next_visit_month,
  lead(visit_month, 2) over (partition by user_id order by visit_month) as next_visit_month2,
  lag(visit_month, 1) over (partition by user_id order by visit_month) as pre_visit_month

from advanced.analytics_function_01
order by user_id, visit_month

결과

image.png
select
  *,
  next_visit_month - visit_month as term
From (
select
  *,
  lead(visit_month, 1) over (partition by user_id order by visit_month) as next_visit_month
from advanced.analytics_function_01)
order by user_id, visit_month
;

결과

image.png
select
  *,
  first_value(visit_month) over (partition by user_id order by visit_month ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as first_visit_month,
  last_value(visit_month) over (partition by user_id order by visit_month ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as last_visit_month

from advanced.analytics_function_01
order by user_id, visit_month
;

결과

image.png

2-8. 윈도우 함수 Frame연습 문제

select
  *,
  sum(amount) over() as amount_total,
  sum(amount) over(order by order_id) as cumulative_sum, -- 누적
  sum(amount) over(partition by user_id order by order_id) as cumulative_sum_user, -- 누적
  avg(amount) over(order by order_id rows between 5 preceding and 1 preceding) as last_5_avg

from `advanced.orders`
order by order_date, user_id
;

결과

image.png

 

2-11. 윈도우 함수 연습 문제(1번)

select
  *,
  count(query_date) over() as total_cnt, # 전체
  count(query_date) over(partition by user) as total_query_cnt
from advanced.query_logs
order by user, query_date
;

결과

image.png

2-11. 윈도우 함수 연습 문제(2번~6번)

with query_cnt_by_team as (
  select 
    extract(WEEK from query_date) as week_number,
    team,
    user,
    count(user) as query_cnt
  from advanced.query_logs
  group by all)
select 
  *,
  rank() over(partition by week_number, team order by query_cnt desc) as team_rank
from query_cnt_by_team
qualify team_rank = 1 
order by week_number, team, query_cnt desc
;

결과

image.png
with query_cnt_by_team as (
  select 
    user,
    team,
    extract(WEEK from query_date) as week_number,
    count(user) as query_cnt
  from advanced.query_logs
  group by all)

select 
  *,
  LAG(query_cnt, 1) OVER (partition by user ORDER BY week_number) AS prev_week_query_count
  -- user 단위, 전주차 week_number
from query_cnt_by_team
-- order by user -- team, query_cnt desc
;

결과

image.png
select 
  *,
  sum(query_cnt) over(partition by user order by query_date) as cumulative_sum,
  -- 왜되는거지? : frame의 default값 : unbounded preceding ~current row  
  sum(query_cnt) over(partition by user order by query_date rows between unbounded preceding and current row) as cumulative_sum2
from (select 
  user,
  team,
  query_date,
  count(*) as query_cnt
from advanced.query_logs
group by all)
-- 검증
-- qualify cumulative_sum != cumulative_sum2
order by user, query_date

;

결과

image.png
WITH raw_data AS (
SELECT DATE '2024-05-01' AS date, 15 AS number_of_orders UNION ALL SELECT DATE '2024-05-02', 13 UNION ALL
SELECT DATE '2024-05-03', NULL UNION ALL
SELECT DATE '2024-05-04', 16 UNION ALL
SELECT DATE '2024-05-05', NULL UNION ALL
SELECT DATE '2024-05-06', 18 UNION ALL
SELECT DATE '2024-05-07', 20 UNION ALL
SELECT DATE '2024-05-08', NULL UNION ALL
SELECT DATE '2024-05-09', 13 UNION ALL
SELECT DATE '2024-05-10', 14 UNION ALL
SELECT DATE '2024-05-11', NULL UNION ALL
SELECT DATE '2024-05-12', NULL
)
SELECT 
  *,
  LAG(number_of_orders) over(order by date) as number_of_orders2,
  ifnull(number_of_orders, LAG(number_of_orders) over(order by date)) as number_of_orders3,
  LAST_VALUE(number_of_orders) over(order by date) as last_value_orders,
  LAST_VALUE(number_of_orders ignore nulls) over(order by date) as last_value_orders2

FROM raw_data
;

결과

image.png
WITH raw_data AS (
SELECT DATE '2024-05-01' AS date, 15 AS number_of_orders UNION ALL SELECT DATE '2024-05-02', 13 UNION ALL
SELECT DATE '2024-05-03', NULL UNION ALL
SELECT DATE '2024-05-04', 16 UNION ALL
SELECT DATE '2024-05-05', NULL UNION ALL
SELECT DATE '2024-05-06', 18 UNION ALL
SELECT DATE '2024-05-07', 20 UNION ALL
SELECT DATE '2024-05-08', NULL UNION ALL
SELECT DATE '2024-05-09', 13 UNION ALL
SELECT DATE '2024-05-10', 14 UNION ALL
SELECT DATE '2024-05-11', NULL UNION ALL
SELECT DATE '2024-05-12', NULL)
-- select * from raw_data;
select 
  * ,
  avg(number_of_orders) over(order by date rows between 2 preceding and current row) as moving_avg
from (SELECT 
  * except(number_of_orders),
  LAST_VALUE(number_of_orders ignore nulls) over(order by date) as number_of_orders
FROM raw_data)
;

결과

image.png

2-11. 윈도우 함수 연습 문제(7번)

with base as (
  select 
    event_date,
    datetime(timestamp_micros(event_timestamp), 'Asia/Seoul') as event_datetime,
    event_name,
    user_id,  
    user_pseudo_id

  from advanced.app_logs
  where 1=1
    and event_date = "2022-08-18"
    and user_pseudo_id = '1997494153.8491999091'), diff_data as(
select 
  *,
  datetime_diff(event_datetime, prev_event_datetime, second) as second_diff -- second로 간격설정
  # second_diff기반으로 새로운 세션의 시작일지 아닐지 판단할 수 있음
from(select 
  *,
  lag(event_datetime, 1) over(partition by user_pseudo_id order by event_datetime) as prev_event_datetime
  # event_datetime이랑 prev_event_datetime을 빼서 20초가 넘으면 새로운 세션으로 정의, 
  # 20초가 넘지 않으면 기존 세션

from base))

select
  *,
  sum(session_start) over(partition by user_pseudo_id order by event_datetime) as session_num
from(select 
  *,
  case
    when prev_event_datetime is null then 1
    when second_diff >= 20 then 1
    else 0
    end as session_start
    # session이 시작됨을 알리는 session_start
from diff_data)
order by event_datetime
limit 20;

결과

image.png

 

느낀점

sql Google-Analytics firebase google-sheets bigquery

답변 1

0

인프런 AI 인턴

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

질문하신 내용을 바탕으로 몇 가지 유사한 질문과 답변을 소개드리겠습니다. 윈도우 함수와 관련된 다양한 활용 예제들은 SQL의 깊이 있는 사용법을 이해하는 데 큰 도움이 될 것입니다. 아래의 링크들이 지용님의 학습에 도움이 되길 바랍니다.

  1. Bigquery 활용편(PDF)파일 P.229 페이지 코드 오류

    • LAST_VALUE 및 윈도우 함수의 동작 원리에 대해 설명하는 사례입니다. FRAME 설정과 관련한 궁금증도 해결 가능합니다.
  2. 퍼널별 유저들의 새로운 세션 시작 횟수의 총합 _ 윈도우 함수 마지막 문제 응용

    • 퍼널 분석을 위한 윈도우 함수 활용 사례로, 다양한 윈도우 함수를 활용하여 데이터를 분석하는 방법을 소개하고 있습니다.
  3. 3-7 리텐션 SQL 쿼리 작성하기 연습 (Weekly, Monthly)

    • 월별, 주별 리텐션 분석을 진행하면서 발생할 수 있는 쿼리 작성 시의 문제 해결법에 대하여 설명합니다.

이 자료들은 윈도우 함수를 사용한 다양한 분석 사례를 제시하며, 실무적인 문제 해결 능력을 키우는데 큰 도움이 될 것입니다. 계속해서 학습하시면서 궁금한 점이 생기면 언제든지 질문해 주세요.

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

최종 과제 제출

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