inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

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

91

DA유치원

작성한 질문수 3

0

1. 윈도우 함수 연습문제 풀이

문제 1)

SELECT  
  user,
  team,
  query_date,
  COUNT(user) OVER (PARTITION BY user) AS total_query_cnt
FROM advanced.query_logs
ORDER BY query_date, team, user
;

문제 2)

WITH weekly_team_query_cnt 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
  week_number,
  team,
  user,
  query_cnt,
  ROW_NUMBER() OVER (PARTITION BY week_number, team ORDER BY query_cnt DESC) AS team_rank
FROM weekly_team_query_cnt
WHERE 1=1
QUALIFY team_rank = 1
ORDER BY week_number, team
;

문제 3)

WITH weekly_team_query_cnt 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, 1) OVER (PARTITION BY user ORDER BY week_number) AS prev_week_query_cnt
FROM weekly_team_query_cnt
ORDER BY user, team, week_number
;

문제 4)

WITH timeseries_user_query_count AS (
  SELECT
    user,
    team,
    query_date,
    COUNT(user) AS query_count
  FROM advanced.query_logs
  GROUP BY ALL
)
SELECT
  user,
  team,
  query_date,
  query_count,
  SUM(query_count) OVER(PARTITION BY user ORDER BY query_date) AS cumulative_query_count
FROM timeseries_user_query_count

문제 5)

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 
  date,
  LAST_VALUE(number_of_orders IGNORE NULLS) OVER (ORDER BY date) AS number_of_orders
FROM raw_data
;

문제 6)

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
  date,
  number_of_orders,
  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
)
;

문제 7)** 새로운 Session 부여하기

  1. 본인 해결 쿼리)

     

WITH create_new_session_app_logs_raw_data AS (
  SELECT
    *,
    LAG(event_datetime) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp) AS before_event_datetime
  FROM (
    SELECT
      event_date,
      event_timestamp,
      DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime,
      event_name,
      user_id,
      user_pseudo_id,
    FROM advanced.app_logs
    WHERE event_date = '2022-08-18'
      AND user_pseudo_id = '1997494153.8491999091'
  )
), 
create_new_session_app_logs AS (
  SELECT
    *,
    IF(second_diff is null OR second_diff > 20, 1, null) AS session_start
  FROM (
    SELECT
      *,
      EXTRACT(second FROM event_datetime - before_event_datetime) AS second_diff
    FROM create_new_session_app_logs_raw_data
  )
)
SELECT
  *,
  SUM(session_start) OVER (ORDER BY event_timestamp) AS session_id
FROM create_new_session_app_logs
;
  1. 카일스쿨님 해결 쿼리)


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 
    event_date = "2022-08-18"
    AND user_pseudo_id = "1997494153.8491999091"
  ORDER BY event_timestamp
), diff_data AS (
  SELECT
    *,
    DATETIME_DIFF(event_datetime, prev_event_datetime, SECOND) AS second_diff
    # 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
  *,
  # 누적합을 사용해서 session_number를 만들었다!
  SUM(session_start) OVER (PARTITION BY user_pseudo_id ORDER BY event_datetime) AS session_num
  # session을 구할 때 쿼리가 길어질 수 있음. 하루에 접속을 여러번 하는 서비스 => session기반이 좋을 수 있고, 아니라고 한다면 일자별 집계가 나을 수 있음
FROM (
  SELECT
    *,
    CASE
      WHEN prev_event_datetime IS NULL THEN 1
      WHEN second_diff >= 20 THEN 1 # session을 나누는 기준 초. 데이터를 탐색하면서 결정
      ELSE NULL
      END AS session_start
      # session이 시작됨을 알리는 session_start
  FROM diff_data
  )
ORDER BY event_datetime
;

 

sql Google-Analytics firebase google-sheets bigquery

답변 1

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다. DA유치원님.

윈도우 함수는 데이터베이스 내에서 데이터를 집계하거나 정렬할 때 매우 유용한 도구입니다. 특히 윈도우 함수를 사용하면 GROUP BY 없이도 데이터를 처리할 수 있어 더욱 강력합니다.

문제 1에 대한 접근 방법

윈도우 함수를 활용하여 사용자별 쿼리 실행 횟수를 구하는 방법을 알아보겠습니다. 윈도우 함수 중 COUNT()를 사용하여, 각 사용자가 실행한 쿼리의 횟수를 같은 테이블 내에서 계산하고자 합니다.

SELECT 
  *, 
  COUNT(*) OVER (PARTITION BY user_id) AS total_queries
FROM 
  query_logs;

위 쿼리에서 OVER 절을 사용하면 전체 테이블에서 윈도우 함수가 작동하는 방법을 지정할 수 있습니다. PARTITION BY를 사용함으로써 각 user_id를 기준으로 데이터를 분리하여 계산할 수 있습니다. 이렇게 하면 각 사용자의 총 쿼리 실행 횟수가 total_queries라는 새로운 컬럼에 추가됩니다.

추가 참고 자료

  • 윈도우 함수의 활용: 기본 윈도우 함수의 사용법과 활용 사례를 다룬 자료를 참고하시기 바랍니다.
  • 윈도우 함수 탐색 함수 연습 문제 - 기존 질문 링크: 윈도우 함수의 다양한 활용 예제가 포함되어 있습니다. 특히 LAST_VALUE와 관련한 실습 문제도 확인해 보세요.

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

최종 과제 제출

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