inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

[빠짝스터디 2주차 과제] 윈도우 함수 연습문제

108

구니

작성한 질문수 2

0

탐색 함수 연습문제 1


1. user 들의 다음 접속 월과 다다음 접속 월을 구하는 쿼리를 작성해주세요

SELECT 
  user_id, 
	visit_month,
  LEAD (visit_month, 1) OVER (PARTITION BY user_id ORDER BY visit_month) AS after_visit_month,
  LEAD (visit_month, 2) OVER (PARTITION BY user_id ORDER BY visit_month) AS after_two_visit_month
FROM advanced.analytics_function_01

 

  1. user 들의 다음 접속 월과 다다음 접속 월, 이전 접속 월을 구하는 쿼리를 작성해주세요

-- 다음접속월 LEAD
-- 다다음접속월 LEAD
-- 이전접속월 LAG
SELECT 
	*,
	LEAD(visit_month, 1) OVER(PARTITION BY user_id ORDER BY visit_month ASC) AS after_visit_month,
	LEAD(visit_month, 2) OVER(PARTITION BY user_id ORDER BY visit_month ASC) AS after_two_visit_month,
	LAG(visit_month) OVER(PARTITION BY user_id ORDER BY visit_month ASC) AS before_visit_month
FROM advanced.analytics_function_01
  1. 유저가 접속했을 때, 다음 접속까지의 간격을 구하시오

-- user_id | visit_month | after_visit_month | diff_month
-- 일단 LEAD, LAG 구하고 after visit month 에서 visit month 뺴기
SELECT *,
  (after_visit_month - visit_month) AS diff_month
FROM (
  SELECT *,
    LEAD(visit_month, 1) OVER(PARTITION BY user_id ORDER BY visit_month) AS after_visit_month,
  FROM advanced.analytics_function_01
) 
ORDER BY user_id, visit_month ASC
길이가 짧은 쿼리

SELECT
	*,
	LEAD(visit_month, 1) OVER (PARTITION BY user_id ORDER BY visit_month) AS after_visit_month,
	LEAD(visit_month, 1) OVER (PARTITION BY user_id ORDER BY visit_month) - visit_month AS diff_month
FROM advanced.analytics_function_01

길이는 더 짧지만 같은 코드가 중복되기 때문에 코드를 수정해야 할 경우 두 번 수정해야함.

  1. user_id 의 첫번째 방문 월, 마지막 방문 월을 구하는 쿼리를 작성해주세요

-- 첫번째방문 : FIRST_VALUE
-- 마지막방문 : LAST_VALUE
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

FRAME 연습문제 2

  1. SUM : amount_total 구하기

  2. 누적합 : cumulative_sum 구하기

  3. 유저별 누적합 : cumulative_sum(user)

  4. 직전 5개 평균값 : last_5_avg ** 직전이므로 current row 포함되면 안 됨

SELECT 
	*,
	-- amount 전체 합
	SUM(amount) OVER() AS amount_total,
	-- 누적 합 cumulative_sum
	SUM(amount) OVER(ORDER BY order_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as cumulative_sum,
	-- 유저별 누적합 cumulative_sum(user)
	SUM(amount) OVER(
		PARTITION BY user_id ORDER BY order_id
		ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
		) as cumulative_sum_user,
	-- 직전 5개 주문의 평균값 last_5_avg
	AVG(amount) OVER(ORDER BY order_id ROWS BETWEEN 5 PRECEDING AND 1 PRECEDING) as last_5_avg
FROM advanced.orders
ORDER BY order_id

 

윈도우 함수 연습문제 3

  1. 사용자별 쿼리를 실행한 총 횟수를 구하는 쿼리를 작성해주세요 단 GROUP BY를 사용해서 집계하는 것이 아닌 query_logs의 데이터의 우측에 새로운 컬럼을 만들어주세요

SELECT 
  *,
  COUNT(query_date) OVER(
	  PARTITION BY user ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
		 ) as total_query_cnt
FROM advanced.query_logs
ORDER BY query_date
  1. 주차별로 팀 내에서 쿼리를 많이 실행한 수를 구한 후, 실행한 수를 활용해 랭킹을 구해주세요. 단, 랭킹이 1등인 사람만 결과가 보이도록 해주세요

WITH weekly AS ( 
-- 날짜를 주로 변환
  SELECT 
    *,
    EXTRACT(WEEK FROM query_date) AS week_number
  FROM advanced.query_logs
),
querycnt AS (
-- 쿼리 실행 횟수 구하기
  SELECT 
    week_number,
    team,
    user,
    COUNT(query_date) OVER (PARTITION BY week_number, user) AS query_cnt
  FROM
    weekly
),
team_ranks AS (
  -- 팀 내에서 쿼리 많이 작성한 사람 랭크 매겨서, 주차별로 파티션 나누고, 랭크 1만 보이게
 SELECT
  week_number,
  team,
  user,
  query_cnt,
  ROW_NUMBER() OVER(PARTITION BY week_number, team ORDER BY query_cnt DESC) AS team_rank
  -- 랭킹 행이 여러개 출력되어서 ROW_NUMBER 로 하나만 나오게 구함 
 FROM
  querycnt
)
SELECT 
  week_number,
  team,
  user,
  query_cnt,
  team_rank
FROM team_ranks
WHERE team_rank = 1
ORDER BY week_number ASC, team ASC;
-- GROUP BY 이용
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
  1. 2번 문제에서 사용한 주차별 쿼리 사용해 쿼리를 실행한 시점 기준 1주전 에 쿼리 실행 수를 별도의 컬럼으로 확인할 수 있는 쿼리를 작성해주세요

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
  user,
  team,
  week_number,
  query_cnt,
  LAG(query_cnt) OVER (PARTITION BY team, user ORDER BY week_number, query_cnt) AS prev_week_query_cnt
FROM
  query_cnt_by_team
ORDER BY user, team
  1. 시간의 흐름에 따라, 일자별로 유저가 실행한 누적 쿼리 수를 작성해주세요

-- 시간의 흐름에 따라 => query_date 기준
-- 유저별, 일자별 쿼리수 합계 => SUM() OVER(PARTITION BY user ~
-- 누적 쿼리수 계산 새 컬럼 cumulative_query_cnt
=> SUM() OVER(PARTITION BY  ORDER BY ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_query_cnt

WITH querycnt AS(
 SELECT 
    user,
    team,
    query_date,
    COUNT(user) AS query_count
  FROM advanced.query_logs
  GROUP BY ALL
  ORDER BY user ASC, query_count DESC
)
SELECT
  user,
  team,
  query_date,
  query_count,
  SUM(query_count) OVER(PARTITION BY team, user ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_query_cnt
FROM
  querycnt
ORDER BY user, query_date ASC, query_count DESC
  1. 다음 데이터는 주문 횟수를 나타낸 데이터입니다. 만약 주문 횟수가 없으면 NULL로 기록됩니다. 이런 데이터에서 NULL 값이라고 되어있는 부분을 바로 이전 날짜의 값으로 채워주는 쿼리를 작성해주세요

SELECT
  *,
  LAST_VALUE(number_of_orders IGNORE NULLS) OVER(ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS last_orders
FROM raw_data
  1. 5번 문제에서 NULL을 채운 후 2일전 ~ 현재의 데이터의 평균을 구하는 쿼리를 작성해주세요

SELECT
  date,
  last_orders,
  AVG(last_orders) OVER(ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) as moving_avg
FROM(
  SELECT
    *,
    LAST_VALUE(number_of_orders IGNORE NULLS) OVER(ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS last_orders
  FROM raw_data
)
  1. app_logs 테이블에서 Custom Session을 만들어주세요. 이전 이벤트 로그와 20초가 지나면 새로운 Session을 만들어주세요 Session은 숫자로 (1,2,3...) 표시해도 됩니다. 2022-08-18일의 user_pseudo_id(1997494153.8491999091)은 session_id가 4까지 나옵니다.

WITH time2 AS (
  SELECT
    event_date,
    event_timestamp,
    TIMESTAMP_MICROS(event_timestamp) + INTERVAL 9 HOUR AS event_datetime,
-- 구글링 검색하다가 한국 시간 기준으로 변환하는 방법찾아서 적용해봄
    event_name,
    user_id,
    user_pseudo_id
  FROM advanced.app_logs
),
lagged_data AS (
  SELECT
    *,
    LAG(event_datetime) OVER(PARTITION BY user_pseudo_id ORDER BY event_datetime) AS before_event_datetime
  FROM
    time2
-- 결과 짧게 보려고 날짜 필터링
  WHERE
    event_date = '2022-08-18'
),
session_data AS (
  SELECT
    *,
    TIMESTAMP_DIFF(event_datetime, before_event_datetime, SECOND) AS second_diff
  FROM
    lagged_data
)
SELECT
  *,
  -- session_start: 첫 이벤트에만 1, 나머지는 NULL
  IF(before_event_datetime IS NULL, 1, NULL) AS session_start,
  -- session_id: 첫 이벤트에서 1로 시작하고, 이후 20초 이상 차이가 생길 때마다 1씩 증가
  SUM(IF(before_event_datetime IS NULL OR second_diff >= 20, 1, 0)) OVER (
    PARTITION BY user_pseudo_id
    ORDER BY event_datetime
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) AS session_id
FROM
  session_data
ORDER BY 
  user_pseudo_id, event_datetime

 

 


sql Google-Analytics firebase google-sheets bigquery

답변 1

0

인프런 AI 인턴

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

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