데이터 분석이나 백엔드 개발을 하다 보면 날짜와 시간을 다루는 경우가 굉장히 많습니다. 예를 들어 "지난주 주문 내역 조회", "회원 가입 후 30일이 지난 고객 찾기", "월별 매출 집계" 같은 작업입니다. SQL에서는 이런 날짜·시간 계산을 도와주는 다양한 함수가 있고, 그중에서도 DATE_ADD, DATEDIFF, EXTRACT는 특히 자주 쓰입니다. 이번 글에서는 이 세 가지 함수를 기본 문법부터 실무 예제까지 상세히 살펴보겠습니다.
DATE_ADD – 날짜에 기간 더하기 / 빼기
DATE_ADD는 날짜에 일정 기간을 더하거나 뺄 때 사용합니다.
예를 들어 오늘 날짜에서 7일 뒤, 혹은 3개월 전 날짜를 쉽게 구할 수 있습니다.
📌 기본 문법
DATE_ADD(date, INTERVAL n unit)
* date: 기준 날짜
* n: 더하거나 뺄 숫자 (음수를 넣으면 빼기)
* unit: 기간 단위 (DAY, MONTH, YEAR, HOUR, MINUTE 등)
📌 기본 예제
-- 오늘 날짜에서 7일 뒤
SELECT DATE_ADD(CURDATE(), INTERVAL 7 DAY);
-- 오늘 날짜에서 3개월 전
SELECT DATE_ADD(CURDATE(), INTERVAL -3 MONTH);
📌 실무 예제
30일 이상 지난 주문 조회
SELECT order_id, order_date
FROM orders
WHERE order_date < DATE_ADD(CURDATE(), INTERVAL -30 DAY);
→ 오늘로부터 30일 이전에 주문된 건들을 조회.
다음 정기 결제일 계산
SELECT user_id, last_payment_date,
DATE_ADD(last_payment_date, INTERVAL 1 MONTH) AS next_payment_date
FROM subscriptions;
→ 마지막 결제일 기준 1개월 뒤를 next_payment_date로 계산.
💡 팁: DATE_SUB라는 함수도 있지만, DATE_ADD에 음수를 주면 같은 효과를 얻을 수 있습니다.
DATEDIFF – 두 날짜 사이의 차이 계산
DATEDIFF는 두 날짜 사이의 일 수 차이를 구합니다.
시간 단위 차이는 지원하지 않고, 오직 날짜(일 단위) 차이만 계산합니다.
📌 기본 문법
DATEDIFF(date1, date2)
* 반환 값: date1 - date2의 일 수
* 결과는 정수이며, 양수/음수 가능
📌 기본 예제
-- 2025-08-10과 2025-08-01의 차이
SELECT DATEDIFF('2025-08-10', '2025-08-01');
-- 결과: 9
📌 실무 예제
회원 가입 후 며칠 지났는지 계산
SELECT user_id, signup_date,
DATEDIFF(CURDATE(), signup_date) AS days_since_signup
FROM users;
→ 현재 날짜와 가입일 차이를 계산해 days_since_signup 컬럼으로 표시.
배송 지연 건 조회
SELECT order_id, order_date,
DATEDIFF(ship_date, order_date) AS days_to_ship
FROM orders
WHERE DATEDIFF(ship_date, order_date) > 5;
→ 주문일과 배송일 차이가 5일 이상인 건만 조회.
💡 주의: DATEDIFF는 순서에 따라 부호가 달라집니다.
* DATEDIFF(later, earlier) → 양수
* DATEDIFF(earlier, later) → 음수
EXTRACT – 날짜/시간에서 특정 요소 추출
EXTRACT는 날짜나 시간 값에서 특정 부분만 뽑아냅니다. 예를 들어 YEAR, MONTH, DAY, HOUR 등을 추출할 수 있습니다.
📌 기본 문법
EXTRACT(unit FROM date)
* unit: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, QUARTER 등
* 반환 값: 해당 단위의 숫자
📌 기본 예제
-- 오늘의 연도, 월, 일 구하기
SELECT EXTRACT(YEAR FROM CURDATE()) AS year_value,
EXTRACT(MONTH FROM CURDATE()) AS month_value,
EXTRACT(DAY FROM CURDATE()) AS day_value;
📌 실무 예제
월별 매출 집계
SELECT EXTRACT(YEAR FROM order_date) AS order_year,
EXTRACT(MONTH FROM order_date) AS order_month,
SUM(amount) AS total_sales
FROM orders
GROUP BY order_year, order_month
ORDER BY order_year, order_month;
→ 주문일에서 연도와 월을 추출해 매출 합계를 계산.
분기별 가입자 수 집계
SELECT EXTRACT(YEAR FROM signup_date) AS signup_year,
EXTRACT(QUARTER FROM signup_date) AS signup_quarter,
COUNT(*) AS total_users
FROM users
GROUP BY signup_year, signup_quarter
ORDER BY signup_year, signup_quarter;
→ 분기별 가입자 수를 계산하여 분기별 성장 추세를 분석.
세 함수 조합 예시
실무에서는 DATE_ADD, DATEDIFF, EXTRACT를 조합해서 사용하는 경우가 많습니다.
예: 30일 내에 재구매한 고객 찾기
WITH first_orders AS (
SELECT customer_id, MIN(order_date) AS first_order_date
FROM orders
GROUP BY customer_id
),
second_orders AS (
SELECT o.customer_id, MIN(o.order_date) AS second_order_date
FROM orders o
JOIN first_orders f ON o.customer_id = f.customer_id
WHERE o.order_date > f.first_order_date
)
SELECT f.customer_id,
f.first_order_date,
s.second_order_date,
DATEDIFF(s.second_order_date, f.first_order_date) AS days_between
FROM first_orders f
JOIN second_orders s ON f.customer_id = s.customer_id
WHERE DATEDIFF(s.second_order_date, f.first_order_date) <= 30;
→ 첫 주문 후 30일 이내에 재구매한 고객 리스트 추출.
마무리
오늘 다룬 DATE_ADD, DATEDIFF, EXTRACT는 날짜·시간 처리에서 가장 자주 쓰이는 기본기입니다.
* DATE_ADD: 기준 날짜에 기간을 더하거나 빼고 싶을 때
* DATEDIFF: 두 날짜 사이의 일 수 차이를 계산할 때
* EXTRACT: 날짜/시간에서 특정 부분을 뽑아낼 때
이 세 가지를 익혀두면, 단순 필터링부터 월별·분기별 집계까지 대부분의 날짜/시간 로직을 구현할 수 있습니다.
특히 EXTRACT는 GROUP BY와 함께 쓰면 매우 강력한 분석 도구가 됩니다.