작성
·
32
0
#1
SELECT
*,
LEAD(visit_month, 1) OVER(PARTITION BY user_id ORDER BY visit_month) AS lead_visit_month1,
LEAD(visit_month, 2) OVER(PARTITION BY user_id ORDER BY visit_month) AS lead_visit_month2
FROM advanced.analytics_function_01
ORDER BY user_id;
#2
SELECT
*,
LEAD(visit_month, 1) OVER(PARTITION BY user_id ORDER BY visit_month) AS after_visit_month1,
LEAD(visit_month, 2) OVER(PARTITION BY user_id ORDER BY visit_month) AS after_visit_month2,
LAG(visit_month, 1) OVER(PARTITION BY user_id ORDER BY visit_month) AS before_visit_month1
FROM advanced.analytics_function_01
ORDER BY
user_id,
visit_month;
#3
SELECT
*,
after_visit_month - visit_month AS diff
FROM (
SELECT
*,
LEAD(visit_month, 1) OVER (PARTITION BY user_id ORDER BY visit_month) AS after_visit_month,
FROM advanced.analytics_function_01
);
#4
SELECT
*,
FIRST_VALUE(visit_month) OVER (PARTITION BY user_id ORDER BY visit_month ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first,
LAST_VALUE(visit_month) OVER (PARTITION BY user_id ORDER BY visit_month ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last
FROM advanced.analytics_function_01;
#5
SELECT
*,
COUNT(user) OVER(PARTITION BY user) AS total_query_cnt
FROM advanced.query_logs
ORDER BY
user,
query_date;
#6
WITH query_cnt_cnt AS (
SELECT
EXTRACT(WEEK FROM query_date) AS week_number,
team,
user,
COUNT(*) AS query_cnt
FROM advanced.query_logs
GROUP BY
week_number,team,user
)
SELECT
*,
RANK() OVER(PARTITION BY week_number, team ORDER BY query_cnt DESC) AS rk
FROM query_cnt_cnt
QUALIFY rk = 1
ORDER BY
week_number,
team,
query_cnt DESC;
#7
WITH query_cnt_cnt AS (
SELECT
EXTRACT(WEEK FROM query_date) AS week_number,
team,
user,
COUNT(*) AS query_cnt
FROM advanced.query_logs
GROUP BY
week_number,team,user
)
SELECT
*,
LAG(query_cnt, 1) OVER (PARTITION BY user ORDER BY week_number) AS prev_week_query_cnt
FROM query_cnt_cnt;
#8
WITH query_cnt AS (
SELECT
*,
COUNT(*) AS query_cnt_cnt
FROM advanced.query_logs
GROUP BY
user, team, query_date
)
SELECT
*,
SUM(query_cnt_cnt) OVER (PARTITION BY user ORDER BY query_date ) AS query_cnt_cnt_cnt
FROM query_cnt;
#9
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
*,
LAST_VALUE(number_of_orders IGNORE NULLS) OVER (ORDER BY date) AS last_value_orders
FROM raw_data;
#10
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
), filled_data AS (
SELECT
* EXCEPT(number_of_orders),
LAST_VALUE(number_of_orders IGNORE NULLS) OVER (ORDER BY date) AS number_of_orders
FROM raw_data
)
SELECT
*,
AVG(number_of_orders) OVER(ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM filled_data
#11
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_date 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
-- DATETIME_DIFF() => 차이를 구할 수 있음
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
FROM diff_data
ORDER BY
event_datetime
)
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. DataPirate님.
윈도우 함수를 활용한 SQL 쿼리 작성 연습 문제에 대한 질문을 올려주셨군요! 윈도우 함수는 데이터를 분석하고 비교 결과를 손쉽게 얻을 수 있도록 도와주는 강력한 도구입니다. 이번 과제를 통해 다양한 윈도우 함수의 사용법을 실습해보신 것 같습니다.
각 쿼리의 주요 부분을 간단히 설명드리겠습니다:
LEAD 함수를 사용하여 현재 행 기준으로 이후의 데이터를 가져오는 방법을 연습합니다. 이는 사용자 ID별로 방문 데이터를 비교할 때 유용합니다.
LAG 함수는 이전 행의 데이터를 가져오는 데 사용됩니다. 사용자 행동의 변화를 추적할 수 있습니다.
LEAD 함수와 함께 수학 연산을 사용하여 데이터를 분석하고 변화를 측정합니다.
FIRST_VALUE 및 LAST_VALUE 함수를 사용하여 각 파티션 내 첫 번째 및 마지막 값을 가져옵니다. 이 구문을 사용할 때 프레임 (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)을 지정해야 올바른 결과를 얻을 수 있다는 점에 주의해야 합니다.
윈도우 함수에서 COUNT 사용은 그룹 내 요소 수를 계산할 때 사용합니다.
6-8. RANK 및 SUM과 같은 집계 함수를 통해 데이터를 그룹화하고 정렬하며 누적 합계를 계산하는 방법을 이해할 수 있습니다.
9-10. NULL 처리와 이동 평균을 계산하는 방식을 활용하여 데이터 간의 공백을 처리하고 시간 간격에 따른 값을 추정합니다.
이 연습을 통해 다양한 시나리오에서 윈도우 함수를 적용하고 분석 하도록 고안된 쿼리로 보입니다.
유사한 질문이나 관련된 이전 답변 예시는 아래 링크에서 찾아보실 수 있습니다:
퍼널별 유저들의 새로운 세션 시작 횟수의 총합 _ 윈도우 함수에서 윈도우 함수를 이용한 세션 분석 방법을 참고하실 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.