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

아더님의 프로필 이미지
아더

작성한 질문수

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

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

작성

·

20

0

  1. 사용자별 쿼리를 실행한 총 횟수

SELECT 
  *,
  COUNT(user) OVER(PARTITION BY user) AS total_query_cnt
FROM advanced.query_logs
ORDER BY user,query_date
  1. 주차별 팀 내 쿼리 실행횟수 1등

SELECT
  *,
  RANK() OVER(PARTITION BY week_number,team ORDER BY query_cnt DESC) AS team_rank
FROM (
  SELECT
    EXTRACT(week FROM query_date) AS week_number,
    team,
    user,
    COUNT(user) AS query_cnt
  FROM advanced.query_logs
  GROUP BY ALL
) AS query_logs_byweek
QUALIFY team_rank = 1
  1. 쿼리 실행시점 기준 1주전 쿼리 실행 횟수

SELECT
  *,
  LAG(query_cnt,1) OVER(ORDER BY week_number) AS prev_week_query_cnt
FROM (
  SELECT
    EXTRACT(week FROM query_date) AS week_number,
    team,
    user,
    COUNT(user) AS query_cnt
  FROM advanced.query_logs
  GROUP BY ALL
) AS query_logs_byweek
  1. 시간의 흐름에 따라, 일자별 유저의 누적 쿼리 실행 수

SELECT
  *,
  SUM(query_count) OVER(PARTITION BY user ORDER BY query_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_query_count
FROM (
  SELECT 
    *,
    COUNT(user) AS query_count
  FROM advanced.query_logs 
  GROUP BY ALL
) AS query_logs_byday
  1. 주문 횟수가 없으면 NULL로 기록된 데이터. NULL값을 이전 날짜의 값으로 채워주기

     

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,
 IF(number_of_orders IS NULL, LAST_VALUE(number_of_orders IGNORE NULLS) OVER(ORDER BY date), number_of_orders) AS number_of_orders
FROM raw_data
ORDER BY date
  1. 5번 문제에서 NULL을 채운 후, 2일전~현재데이터의 평균을 구하는 쿼리(이동 평균)

SELECT 
  *,
  AVG(number_of_orders) OVER(ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM (
  SELECT
  date,
  IF(number_of_orders IS NULL, LAST_VALUE(number_of_orders IGNORE NULLS) OVER(ORDER BY date), number_of_orders) AS number_of_orders
  FROM raw_data
) AS data
  1. app_logs테이블에서 custom session 만들기. 이전 이벤트 로그와 20초가 지나면 새로운 session을 표시(숫자로 1,2,3,..)

WITH base AS (
SELECT
  event_date,
  DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul') AS event_datetime,
  event_name,
  user_pseudo_id
FROM advanced.app_logs
WHERE 
  user_pseudo_id = '1997494153.8491999091'
  AND event_date = '2022-08-18'
)
SELECT 
  *,
  SUM(session_start) OVER(PARTITION BY user_pseudo_id ORDER BY event_datetime) AS session_num
FROM (
  SELECT
    *,
    CASE 
      WHEN second_diff IS NULL THEN 1
      WHEN second_diff >= 20 THEN 1
    END AS session_start
  FROM (
    SELECT
      *,
      Lag(event_datetime,1) OVER(PARTITION BY user_pseudo_id ORDER BY event_datetime) AS before_event_datetime,
      DATETIME_DIFF(event_datetime, Lag(event_datetime,1) OVER(PARTITION BY user_pseudo_id ORDER BY event_datetime),SECOND) AS second_diff
    FROM base
  ) AS A
) AS B

답변 1

0

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

아더님이 작성한 BigQuery 연습 문제와 그 해결 방법들 정말 잘 정리되어 있군요! 아래에 각 문제의 요약과 해당하는 쿼리에 대한 간단한 설명을 덧붙이겠습니다.

  1. 사용자별 쿼리 실행 총 횟수

    • 주어진 테이블에서 각 사용자별 쿼리 실행 수를 계산합니다.
    • COUNT(user) OVER(PARTITION BY user) 를 통해 사용자별 총 쿼리 횟수를 집계합니다.
  2. 주차별 팀 내 쿼리 실행횟수 1등

    • 주차와 팀별로 가장 많은 쿼리를 실행한 사용자를 찾습니다.
    • RANK() 함수를 사용하여 팀 내부 순위를 매기고, team_rank = 1로 가장 높은 사용자를 추출합니다.
  3. 쿼리 실행 시점 기준 1주 전 쿼리 실행 횟수

    • 현재 주의 사용자별 쿼리 횟수와 1주 전 그 사용자가 쿼리를 몇 번 실행했는지를 비교합니다.
    • LAG() 함수를 사용하여 전주의 쿼리 실행 횟수를 가져옵니다.
  4. 일자별 유저의 누적 쿼리 실행 수

    • 특정 날짜까지 사용자별로 실행한 쿼리의 누적 합계를 계산합니다.
    • SUM(query_count) OVER(PARTITION BY user ORDER BY query_date)를 사용하여 누적합을 구합니다.
  5. 주문 횟수가 없으면 NULL로 기록된 데이터의 NULL값을 이전 날짜 값으로 채우기

    • 데이터의 NULL 값을 이전의 주문 수로 대체합니다.
    • LAST_VALUE() IGNORE NULLS를 사용하여 NULL 값 대체를 수행합니다.
  6. 2일 전부터 현재 계산된 데이터를 이용한 이동 평균

    • NULL 채운 후, 최근 2일을 포함한 이동 평균을 계산하여 제공함.
    • AVG() OVER(ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)를 사용해 이동 평균을 계산합니다.
  7. 20초 이상 경과시 새로운 session을 표시

    • 사용자가 이벤트 로그에서 20초 이상 경과했을 때 새로운 세션을 시작으로 표시합니다.
    • LAG()DATETIME_DIFF()를 사용하여 시간 차이를 계산하고, SUM()을 사용하여 구간별 세션 번호를 매깁니다.

각 쿼리는 고급 쿼리 작성을 위한 윈도우 함수의 사용법을 잘 보여주고 있습니다. 여러분의 연습 문제 풀이가 매우 유용한 학습이 되기를 바랍니다. 궁금한 점이 있으면 언제든지 물어보세요!

출처: BigQuery SQL Documentation

아더님의 프로필 이미지
아더

작성한 질문수

질문하기