작성
·
33
0
SELECT
user_id,
visit_month,
LEAD(visit_month, 1) OVER(PARTITION BY user_id ORDER BY visit_month) as next_visit_month,
LEAD(visit_month, 2) OVER(PARTITION BY user_id ORDER BY visit_month) as two_next_visit_month,
FROM advanced.analytics_function_01
ORDER BY user_id
SELECT
user_id,
visit_month,
LAG(visit_month, 1) OVER(PARTITION BY user_id ORDER BY visit_month) as prev_visit_month,
LEAD(visit_month, 1) OVER(PARTITION BY user_id ORDER BY visit_month) as next_visit_month,
LEAD(visit_month, 2) OVER(PARTITION BY user_id ORDER BY visit_month) as two_next_visit_month,
FROM advanced.analytics_function_01
ORDER BY user_id
SELECT
user_id,
visit_month,
FIRST_VALUE(visit_month) OVER(PARTITION BY user_id ORDER BY visit_month) as first_visit_month,
LAST_VALUE(visit_month) OVER(PARTITION BY user_id ORDER BY visit_month) as last_visit_month,
FROM advanced.analytics_function_01
ORDER BY user_id
advanced.order 문제
SELECT
*,
SUM(amount) OVER() as amount_total,
SUM(amount) OVER(ORDER BY order_id) as cumulative_sum,
SUM(amount) OVER(PARTITION BY user_id ORDER BY order_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as cumulative_sum_by_user,
AVG(amount) OVER(ORDER BY order_id ROWS BETWEEN 5 PRECEDING AND 1 PRECEDING) as last_5_orders_avg_amount,
FROM advanced.orders
ORDER BY order_id, user_id
SELECT
*,
COUNT(*) OVER(PARTITION BY user) as total_query_cnt
FROM advanced.query_logs
ORDER BY user
WITH base 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 base
QUALIFY team_rank=1
ORDER BY week_number
WITH base as (
SELECT
user,
team,
EXTRACT(WEEK FROM query_date) as week_number,
COUNT(user) as query_cnt,
FROM advanced.query_logs
GROUP BY ALL
)
SELECT
*,
LAG(query_cnt, 1) OVER(PARTITION BY user ORDER BY week_number) as prev_week_query_count
FROM base
WITH base as (
SELECT
user,
team,
query_date,
COUNT(user) as query_count,
FROM advanced.query_logs
GROUP BY ALL
)
SELECT
*,
SUM(query_count) OVER(PARTITION BY user ORDER BY query_date) as cumulative_query_count
FROM base
ORDER BY user
-- SELECT
-- *,
-- IF(number_of_orders is NULL, prev_number_of_orders, number_of_orders) as result_number_of_orders,
-- FROM (
-- SELECT
-- *,
-- LAG(number_of_orders, 1) OVER(ORDER BY date) as prev_number_of_orders
-- FROM raw_data
-- )
-- 이 방법은 전의 값들이 Null이 여러개면 제대로 안나옴...!
SELECT
*,
IF(number_of_orders is NULL, last_number_of_orders, number_of_orders) as result_number_of_orders,
FROM (
SELECT
*,
LAST_VALUE(number_of_orders IGNORE NULLS) OVER(ORDER BY date) as last_number_of_orders
FROM raw_data
)
SELECT
*,
AVG(result_number_of_orders) OVER(ORDER BY date ROWS BETWEEN 2 PRECEDING and CURRENT ROW) as moving_avg
FROM (
SELECT
*,
IF(number_of_orders is NULL, last_number_of_orders, number_of_orders) as result_number_of_orders,
FROM (
SELECT
*,
LAST_VALUE(number_of_orders IGNORE NULLS) OVER(ORDER BY date) as last_number_of_orders
FROM raw_data
)
)
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
FROM advanced.app_logs
WHERE event_date = '2022-08-18' and user_pseudo_id = '1997494153.8491999091'
),
base2 as (
SELECT
*,
LAG(event_datetime, 1) OVER(PARTITION BY user_pseudo_id ORDER BY event_datetime) as before_event_datetime
FROM base
)
SELECT
*,
SUM(session_start) OVER(PARTITION BY user_pseudo_id ORDER BY event_timestamp) as session_id
FROM (
SELECT
*,
IF(second_diff is NULL or second_diff > 20, 1, NULL) as session_start
FROM (
SELECT
*,
DATETIME_DIFF(event_datetime, before_event_datetime, second) as second_diff
FROM base2
)
)
ORDER BY event_timestamp
EXTRACT(WEEK FROM query_date) as week_number
: date 정보에서 week 정보 등을 추출할 수 있는 함수
DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') as event_datetime
: timestamp 형태의 데이터를 날짜로 바꿀 수 있는 함수
LAST_VALUE(number_of_orders IGNORE NULLS)...
그냥 마지막 값은 LAST_VALUE, 이전 데이터 중 null값이 아닌 마지막 값을 가져오고 싶을 때는 IGNORE NULLS
를 사용해야 함. (5번 연습문제에서 처음에는 LAG 함수를 사용해서 null이 여러 개 연속인 경우가 있어 제대로 값을 가져오지 못했고, LAST_VALUE 윈도우 함수에서IGNORE NULLS
를 까먹어서 null 처리가 또 안됐었다.)
With절과 서브쿼리 절을 어떤 상황에 사용할지 아직 잘 모르겠다.
CASE WHEN절 사용법이 익숙치 않았다. (문제를 풀 때 IF절을 사용했던 부분에서 강의에서는 CASE WHEN을 사용)
윈도우 함수를 제대로 처음 배워봤는데, 어려웠지만 유용한 부분이 많아 사용할 일이 많을 것 같다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 김승규님.
윈도우 함수 및 다양한 BigQuery 기능에 대한 실습을 진행하신 것에 대해 공유해 주셔서 감사합니다. 윈도우 함수는 SQL에서 굉장히 유용한 기능으로, 데이터의 복잡한 분석에 특히 유리합니다. 각종 함수와 메소드를 통해 데이터를 더욱 의미 있게 해석하고 처리할 수 있습니다.
김승규님의 연습에서처럼 LEAD
, LAG
, FIRST_VALUE
, LAST_VALUE
와 같은 함수들을 사용하면, 순서에 따라 데이터의 앞뒤 값들을 손쉽게 비교하거나 참조할 수 있어 데이터 패턴을 파악하는 데 큰 도움이 됩니다. 또한, 데이터를 그룹화하고 특정 기준에 따라 순위를 매기거나 집계하는 데 윈도우 함수는 매우 유용합니다.
아래의 링크에서는 윈도우 함수와 관련된 다양한 예제와 논의를 확인하실 수 있습니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.