작성
·
52
·
수정됨
0
-- 출제의도: 윈도우 함수(LEAD)를 사용하여 파티션을 나눠 데이터를 탐색할 수 있는가?
SELECT
user_id
, visit_month AS visit_month_m0
, LEAD(visit_month) OVER (PARTITION BY user_id ORDER BY visit_month) AS visit_month_m1
, LEAD(visit_month, 2) OVER (PARTITION BY user_id ORDER BY visit_month) AS visit_month_m2
FROM advanced.analytics_function_01
ORDER BY user_id;
-- 출제의도: 윈도우 함수(LEAD)와 (LAG)을 함께 사용하여 파티션을 나눠 데이터를 탐색할 수 있는가?
SELECT
user_id
, visit_month AS visit_month_m0
, LEAD(visit_month) OVER (PARTITION BY user_id ORDER BY visit_month) AS visit_month_m1
, LEAD(visit_month, 2) OVER (PARTITION BY user_id ORDER BY visit_month) AS visit_month_m2
, LAG(visit_month) OVER (PARTITION BY user_id ORDER BY visit_month) AS visit_month_p1
FROM advanced.analytics_function_01
ORDER BY user_id;
SELECT
order_id
, order_date
, user_id
, amount
, SUM(amount) OVER (ORDER BY order_date, order_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS amount_total
, SUM(amount) OVER (ORDER BY order_date, order_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_sum
, SUM(amount) OVER (PARTITION BY user_id ORDER BY order_date, order_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_sum_by_user
, AVG(amount) OVER (ORDER BY order_date, order_id ROWS BETWEEN 5 PRECEDING AND 1 PRECEDING) AS last_5_orders_avg_amount
FROM advanced.orders
--QUALIFY last_5_orders_avg_amount >= 150
ORDER BY order_id;
-- 출제의도: 윈도우 함수의 집계 함수 중 COUNT를 사용할 수 있는가?
SELECT
*
, COUNT(user) OVER (PARTITION BY user) AS total_query_cnt
FROM advanced.query_logs
ORDER BY query_date, user;
-- 출제의도: GROUP BY와 윈도우 함수(순위)를 함께 사용할 수 있는가?
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)
QUALIFY team_rank = 1
ORDER BY week_number, team;
-- 출제의도: GROUP BY와 윈도우 함수(LAG)를 함께 사용할 수 있는가?
SELECT
*
, LAG(query_cnt) OVER (PARTITION BY user ORDER BY week_number) AS prev_week_query_count
FROM
(SELECT
user
, team
, EXTRACT(WEEK FROM query_date) AS week_number
, COUNT(user) AS query_cnt
FROM advanced.query_logs
GROUP BY ALL)
ORDER BY user, week_number;
-- *FRAME의 DEFAULT 값: UNBOUNDED PRECEDING ~ CURRENT ROW
-- 출제의도: GROUP BY와 윈도우 함수(SUM-누계합)를 함께 사용할 수 있는가?
SELECT
*
, SUM(query_cnt) OVER (PARTITION BY user ORDER BY query_date) AS cumulative_query_count
FROM
(SELECT
user
, team
, query_date
, COUNT(user) AS query_cnt
FROM advanced.query_logs
GROUP BY ALL)
ORDER BY user, query_date;
-- 출제의도: 윈도우 함수(LAST_VALUE)에서 IGNORE NULLS가 필요한 상황을 이해할 수 있는가?
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
-- , IFNULL(number_of_orders, LAG(number_of_orders) OVER (ORDER BY date)) AS number_of_orders
-- FROM raw_data
-- ORDER BY date;
SELECT
*
, LAST_VALUE(number_of_orders IGNORE NULLS) OVER (ORDER BY date) AS number_of_orders
FROM raw_data
ORDER BY date;
-- 출제의도: 예외 값을 처리한 이후, 윈도우 함수로 이동 평균을 계산할 수 있는가?
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
*
, ROUND(AVG(number_of_orders) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
, 1) AS moving_avg
FROM(
SELECT
date
, IFNULL(number_of_orders, LAG(number_of_orders) OVER (ORDER BY date)) AS number_of_orders
FROM raw_data)
ORDER BY date;
-- *Session은 숫자로(1,2,3…) 표시해도 됩니다.
-- **2022-08-18일의 user_pseudo_id(1997494153. 8491999091)은 session_id가 4까지 나옵니다
-- 출제의도: 윈도우 함수를 웹 로그 데이터에 적용하여 활용할 수 있는가?
-- Step 1. Session 정보 추출
WITH base AS(
SELECT
event_date
, event_timestamp
, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime
, event_name
, user_id
, user_pseudo_id
, DATETIME(TIMESTAMP_MICROS(LAG(event_timestamp) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp)), 'Asia/Seoul') AS before_event_datetime
FROM advanced.app_logs
WHERE event_date = '2022-08-18'
AND user_pseudo_id = '1997494153.8491999091'
),
-- Step 2. 세션 유지 시간 및 신규 세션 여부 계산
session_info AS(
SELECT
*
, TIMESTAMP_DIFF(event_datetime, before_event_datetime, SECOND) AS second_diff
, CASE
WHEN TIMESTAMP_DIFF(event_datetime, before_event_datetime, SECOND) >= 20
OR TIMESTAMP_DIFF(event_datetime, before_event_datetime, SECOND) IS NULL THEN 1
ELSE NULL
END AS session_start
FROM base
)
-- Step 3. 신규 세션 id 세팅
SELECT
*
, SUM(session_start) OVER (PARTITION BY user_pseudo_id ORDER BY event_datetime) AS session_id
FROM session_info
ORDER BY event_date, event_timestamp;
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 김하제님.
윈도우 함수, 특히 LEAD와 LAG 함수의 활용법에 대해 질문해주셨군요. 이를 통해 데이터 분석에서 시계열 데이터를 탐색하고 원하는 결과를 도출하는데 매우 유용함을 알 수 있습니다. 김하제님께서 작성하신 SQL 쿼리는 다음 접속월, 다다음 접속월 및 이전 접속월을 구하는 방법을 잘 보여주고 있습니다. 이러한 윈도우 함수는 특정 파티션 내에서 데이터를 순서대로 정렬하고 탐색할 수 있게 도와줍니다.
관련하여 도움이 될만한 유사한 질문과 답변 링크들을 소개합니다:
Bigquery 활용편(PDF)파일 P.229 페이지 코드 오류 해결
windows function default 값에 대하여 range between과 rows between의 차이
이 유사한 질문들을 통해 각 윈도우 함수의 성능이나 가능한 실수들을 이해하며 개선할 수 있는 기회가 되실 것입니다. 궁금하신 점이 있으면 언제든지 추가로 질문해 주세요!
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.