Skip to Content

날짜/시간 함수를 활용한 매출 분석

초급중급

학습 목표

이 레시피를 완료하면 다음을 할 수 있습니다:

  • BigQuery의 날짜/시간 데이터 타입 (DATE, DATETIME, TIMESTAMP) 이해
  • EXTRACT, DATE_TRUNC 함수로 시간 단위 추출
  • DATE_ADD/SUB로 기간 비교 분석
  • DATE_DIFF로 기간 계산 및 KPI 도출

BigQuery 실행 환경 설정

from google.cloud import bigquery import pandas as pd # 인증 설정 (서비스 계정 키 사용 시) # import os # os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "path/to/your-key.json" # BigQuery 클라이언트 생성 client = bigquery.Client(project='your-project-id') # 쿼리 실행 함수 def run_query(query): return client.query(query).to_dataframe()
ℹ️
프로젝트 ID 설정

위 코드에서 your-project-id를 본인의 GCP 프로젝트 ID로 변경하세요.


1. DATE vs DATETIME vs TIMESTAMP

이론

BigQuery는 세 가지 주요 시간 데이터 타입을 제공합니다:

타입형식예시특징
DATEYYYY-MM-DD2024-01-15날짜만 저장, 시간 정보 없음
DATETIMEYYYY-MM-DD HH:MM:SS2024-01-15 14:30:00날짜 + 시간, 타임존 없음
TIMESTAMPYYYY-MM-DD HH:MM:SS UTC2024-01-15 14:30:00+00:00날짜 + 시간 + 타임존 (UTC 기준)
ℹ️
언제 어떤 타입을 사용할까?
  • DATE: 생년월일, 가입일 등 시간이 중요하지 않은 경우
  • DATETIME: 로컬 시간 기준 이벤트 (예약 시간, 영업 시간)
  • TIMESTAMP: 전 세계에서 발생하는 이벤트의 정확한 시점 기록 (주문 시간, 로그)

주요 함수

-- 현재 날짜/시간 조회 CURRENT_DATE() -- 현재 날짜 CURRENT_DATETIME() -- 현재 날짜시간 CURRENT_TIMESTAMP() -- 현재 타임스탬프 -- 타입 변환 CAST(timestamp_col AS DATE) -- TIMESTAMP → DATE CAST(timestamp_col AS DATETIME) -- TIMESTAMP → DATETIME

실습: 날짜 타입 비교

SELECT CURRENT_DATE() AS current_date, CURRENT_DATETIME() AS current_datetime, CURRENT_TIMESTAMP() AS current_timestamp, -- created_at을 각 타입으로 변환 CAST(created_at AS DATE) AS order_date, CAST(created_at AS DATETIME) AS order_datetime, created_at AS order_timestamp FROM `your-project-id.thelook_ecommerce.orders` LIMIT 5
실행 결과
current_datecurrent_datetimecurrent_timestamporder_dateorder_datetimeorder_timestamp
2024-11-192024-11-19 10:26:432024-11-19 10:26:43+00:002023-10-112023-10-11 15:31:002023-10-11 15:31:00+00:00

2. EXTRACT 함수 - 연/월/일/요일 추출

이론

EXTRACT 함수는 날짜/시간에서 특정 부분만 추출합니다.

EXTRACT(part FROM date_expression)
Part설명반환값 범위
YEAR연도예: 2024
MONTH1-12
DAY1-31
DAYOFWEEK요일1(일)~7(토)
DAYOFYEAR연중 일수1-366
WEEK주차0-53
QUARTER분기1-4
HOUR시간0-23
MINUTE0-59
⚠️
요일 주의사항

BigQuery의 DAYOFWEEK는 일요일이 1, 토요일이 7입니다.

실습: 요일별 주문 분석

SELECT EXTRACT(DAYOFWEEK FROM created_at) AS day_of_week, CASE EXTRACT(DAYOFWEEK FROM created_at) WHEN 1 THEN '일요일' WHEN 2 THEN '월요일' WHEN 3 THEN '화요일' WHEN 4 THEN '수요일' WHEN 5 THEN '목요일' WHEN 6 THEN '금요일' WHEN 7 THEN '토요일' END AS day_name, COUNT(*) AS order_count FROM `your-project-id.thelook_ecommerce.orders` GROUP BY day_of_week, day_name ORDER BY day_of_week
실행 결과
day_of_weekday_nameorder_count
1일요일18,384
2월요일17,916
3화요일17,617
4수요일17,313
5목요일17,526
6금요일17,725
7토요일18,312
💡
인사이트

주말(토/일)의 주문이 평일보다 약간 많습니다. 이커머스에서는 흔한 패턴으로, 주말 프로모션 전략 수립에 활용할 수 있습니다.


3. DATE_TRUNC - 기간 단위 집계

이론

DATE_TRUNC는 날짜를 특정 단위로 잘라냅니다. 월별, 주별, 분기별 집계에 유용합니다.

DATE_TRUNC(date_expression, date_part)
date_part입력결과
DAY2024-03-15 14:30:002024-03-15
WEEK2024-03-15 14:30:002024-03-11 (월요일)
MONTH2024-03-15 14:30:002024-03-01
QUARTER2024-03-15 14:30:002024-01-01
YEAR2024-03-15 14:30:002024-01-01

실습: 월별 매출 트렌드

SELECT DATE_TRUNC(CAST(o.created_at AS DATE), MONTH) AS month, COUNT(DISTINCT o.order_id) AS order_count, COUNT(DISTINCT o.user_id) AS customer_count, SUM(oi.sale_price) AS total_revenue, ROUND(SUM(oi.sale_price) / COUNT(DISTINCT o.order_id), 2) AS avg_order_value FROM `your-project-id.thelook_ecommerce.orders` o JOIN `your-project-id.thelook_ecommerce.order_items` oi ON o.order_id = oi.order_id WHERE o.created_at >= '2024-01-01' GROUP BY month ORDER BY month
실행 결과
monthorder_countcustomer_counttotal_revenueavg_order_value
2024-01-011,9831,892156,234.5078.78
2024-02-011,9281,845148,923.7577.24
2024-03-012,2092,098172,456.3078.07

4. DATE_DIFF - 기간 계산

이론

DATE_DIFF는 두 날짜 사이의 차이를 계산합니다.

DATE_DIFF(end_date, start_date, date_part)
계산SQL결과
일수 차이DATE_DIFF('2024-03-15', '2024-03-10', DAY)5
월수 차이DATE_DIFF('2024-06-01', '2024-03-01', MONTH)3
연수 차이DATE_DIFF('2025-01-01', '2024-01-01', YEAR)1

실습: 고객 활동 기간 분석

SELECT user_id, MIN(CAST(created_at AS DATE)) AS first_order_date, MAX(CAST(created_at AS DATE)) AS last_order_date, DATE_DIFF(MAX(CAST(created_at AS DATE)), MIN(CAST(created_at AS DATE)), DAY) AS days_active, COUNT(DISTINCT order_id) AS total_orders, ROUND( COUNT(DISTINCT order_id) * 1.0 / NULLIF(DATE_DIFF(MAX(CAST(created_at AS DATE)), MIN(CAST(created_at AS DATE)), MONTH), 0), 2 ) AS orders_per_month FROM `your-project-id.thelook_ecommerce.orders` GROUP BY user_id HAVING COUNT(DISTINCT order_id) > 1 -- 2회 이상 주문 고객만 ORDER BY days_active DESC LIMIT 10
실행 결과
user_idfirst_order_datelast_order_datedays_activetotal_ordersorders_per_month
45232023-01-022024-11-1568280.35
78912023-01-052024-10-2866250.23
23452023-01-082024-10-2065160.28

5. 전월/전년 대비 분석

이론

시계열 분석에서 가장 중요한 것은 기간 대비 비교입니다. 전월 대비(MoM), 전년 대비(YoY) 성장률을 계산하는 방법을 알아봅니다.

-- 전월 데이터 조인 DATE_SUB(current_month, INTERVAL 1 MONTH) -- 전년 동월 데이터 조인 DATE_SUB(current_month, INTERVAL 1 YEAR)

실습: 전월 대비 매출 성장률

WITH monthly_revenue AS ( SELECT DATE_TRUNC(CAST(o.created_at AS DATE), MONTH) AS month, SUM(oi.sale_price) AS revenue FROM `your-project-id.thelook_ecommerce.orders` o JOIN `your-project-id.thelook_ecommerce.order_items` oi ON o.order_id = oi.order_id GROUP BY month ) SELECT curr.month, curr.revenue AS current_revenue, prev.revenue AS previous_revenue, ROUND((curr.revenue - prev.revenue) / prev.revenue * 100, 2) AS mom_growth_pct FROM monthly_revenue curr LEFT JOIN monthly_revenue prev ON curr.month = DATE_ADD(prev.month, INTERVAL 1 MONTH) WHERE curr.month >= '2024-01-01' ORDER BY curr.month
실행 결과
monthcurrent_revenueprevious_revenuemom_growth_pct
2024-01-01156,234.50142,567.809.58
2024-02-01148,923.75156,234.50-4.68
2024-03-01172,456.30148,923.7515.80
💡
실무 활용
  • MoM (Month over Month): 단기 트렌드 파악, 계절성 영향 큼
  • YoY (Year over Year): 계절성 제거, 중장기 성장 추세 파악
  • QoQ (Quarter over Quarter): 분기별 사업 목표 달성도 측정

퀴즈

문제 1: 시간대별 주문 분석

orders 테이블에서:

  1. 주문 시간(시)을 추출하여 시간대별 주문 건수를 집계하세요
  2. 어떤 시간대에 주문이 가장 많은지 파악하세요

정답 보기

SELECT EXTRACT(HOUR FROM created_at) AS hour, COUNT(*) AS order_count, ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER(), 2) AS pct FROM `your-project-id.thelook_ecommerce.orders` GROUP BY hour ORDER BY hour

해설:

  • EXTRACT(HOUR FROM created_at)로 시간을 추출합니다
  • 윈도우 함수 SUM(...) OVER()로 전체 대비 비율을 계산합니다
  • 일반적으로 오후 2-4시, 저녁 8-10시에 주문이 집중됩니다

문제 2: 주문 후 배송까지 소요 기간

order_items 테이블에서:

  1. 배송 완료된 주문의 평균 배송 소요일을 계산하세요
  2. 월별로 배송 소요일 추이를 분석하세요

정답 보기

SELECT DATE_TRUNC(CAST(shipped_at AS DATE), MONTH) AS month, COUNT(*) AS delivered_count, ROUND(AVG(DATE_DIFF(CAST(delivered_at AS DATE), CAST(shipped_at AS DATE), DAY)), 2) AS avg_delivery_days FROM `your-project-id.thelook_ecommerce.order_items` WHERE delivered_at IS NOT NULL GROUP BY month ORDER BY month

해설:

  • DATE_DIFF로 배송 시작일과 완료일의 차이를 계산합니다
  • AVG로 평균을 구합니다
  • NULL 체크로 실제 배송 완료된 건만 필터링합니다

정리

함수용도예시
EXTRACT날짜에서 특정 부분 추출요일별, 시간대별 분석
DATE_TRUNC날짜를 특정 단위로 절삭월별, 분기별 집계
DATE_DIFF두 날짜 간 차이 계산리텐션, 배송 소요일
DATE_ADD/SUB날짜 더하기/빼기전월/전년 대비 분석

다음 단계

날짜/시간 함수를 마스터했습니다! 다음으로 그룹화와 집계에서 더 복잡한 집계 분석을 배워보세요.

Last updated on

🤖AI 모의면접실전처럼 연습하기