16. [SQL 코테] LAG + DATEDIFF 조합 완전 정복

Jason·2026년 1월 14일

SQL

목록 보기
16/47

< 한줄요약 >
1. DATEDIFF는 윈도우 함수 아님
2. LAG 결과를 DATEDIFF 인자로 바로 사용 가능
3. 같은 SELECT에서 별칭 참조 불가 → CTE 분리 or 함수 중첩
4. DATEDIFF 순서: 현재 - 과거 = 양수
5. NULL 체크는 원인(prev_order_date)으로 하면 더 명확

.
.
.

[SQL 코테] LAG + DATEDIFF 조합 완전 정복 🔥

📝 문제: 일주일 내 재구매 고객 찾기

테이블 구조

orders 테이블
order_id | user_id | order_date
---------|---------|------------
1        | 101     | 2024-01-01
2        | 102     | 2024-01-03
3        | 101     | 2024-01-05
4        | 103     | 2024-01-10
5        | 101     | 2024-01-20
6        | 102     | 2024-01-25

요구사항

  • 이전 구매일로부터 7일 이내에 재구매한 기록 찾기
  • 결과 컬럼: user_id, prev_order_date, order_date, days_diff

✅ 정답 쿼리

WITH lagged AS ( 
  SELECT    
    order_id, 
    user_id, 
    order_date,   
    LAG(order_date) OVER(PARTITION BY user_id ORDER BY order_date) AS prev_order_date,
    DATEDIFF(order_date, LAG(order_date) OVER(PARTITION BY user_id ORDER BY order_date)) AS days_diff
  FROM orders
)
SELECT   
  user_id, 
  prev_order_date,  
  order_date, 
  days_diff 
FROM lagged 
WHERE days_diff <= 7 
  AND prev_order_date IS NOT NULL 
ORDER BY order_date;

결과

user_id | prev_order_date | order_date | days_diff
--------|-----------------|------------|----------
101     | 2024-01-01      | 2024-01-05 | 4

💡 핵심 포인트 5가지

1️⃣ DATEDIFF는 윈도우 함수가 아니다!

-- ❌ 틀린 문법
DATEDIFF(order_date, prev_order_date) OVER(PARTITION BY user_id ORDER BY order_date)

-- ✅ 맞는 문법 - DATEDIFF는 그냥 일반 함수
DATEDIFF(order_date, prev_order_date)

2️⃣ LAG 결과를 DATEDIFF 인자로 바로 사용 가능

LAG는 복잡해 보이지만 결국 날짜 값 하나를 반환한다.

DATEDIFF(
  order_date,                                                      -- 인자1: 날짜
  LAG(order_date) OVER(PARTITION BY user_id ORDER BY order_date)   -- 인자2: 이것도 날짜!
) AS days_diff

비유하자면:

-- 이게 되는 것처럼
DATEDIFF('2024-01-05', '2024-01-01')

-- 이것도 되는 거다
DATEDIFF(order_date, [LAG가 반환한 날짜값])

3️⃣ 같은 SELECT에서 별칭 참조 불가

-- ❌ 안 됨 - 같은 SELECT에서 방금 만든 별칭 참조
SELECT 
  LAG(order_date) OVER(...) AS prev_order_date,
  DATEDIFF(order_date, prev_order_date) AS days_diff  -- 에러!

해결 방법 2가지:

A) CTE에서 LAG만 하고, 메인에서 DATEDIFF

WITH lagged AS (
  SELECT 
    user_id, order_date,
    LAG(order_date) OVER(PARTITION BY user_id ORDER BY order_date) AS prev_order_date
  FROM orders
)
SELECT 
  user_id, prev_order_date, order_date,
  DATEDIFF(order_date, prev_order_date) AS days_diff
FROM lagged
WHERE prev_order_date IS NOT NULL
  AND DATEDIFF(order_date, prev_order_date) <= 7;

B) CTE에서 LAG를 DATEDIFF 안에 직접 넣기 (내가 사용한 방법)

DATEDIFF(order_date, LAG(order_date) OVER(...)) AS days_diff

4️⃣ DATEDIFF 순서 주의: 현재 - 과거 = 양수

DATEDIFF(date1, date2) = date1 - date2
DATEDIFF('2024-01-05', '2024-01-01') = 4   -- 양수 ✅
DATEDIFF('2024-01-01', '2024-01-05') = -4  -- 음수 ❌

꿀팁: "지금 - 과거 = 양수" 로 기억하자!

5️⃣ NULL 체크는 원인으로 하면 더 명확

-- 이것도 동작하지만
WHERE days_diff IS NOT NULL

-- 이게 의미가 더 명확하다 (직전 구매가 있는 경우만)
WHERE prev_order_date IS NOT NULL

days_diff가 NULL인 이유 = prev_order_date가 없어서
→ 원인을 직접 명시하는 게 더 명확!


🎯 라이브 코테 체크리스트

  • DATEDIFF에 OVER() 붙이지 않기
  • 같은 SELECT에서 별칭 참조하려고 하지 않기
  • DATEDIFF 인자 순서: (현재, 과거)
  • FROM 절 빠뜨리지 않기
  • 쉼표 누락 체크

채널톡 DA 인턴 코테 준비 중 정리한 내용입니다 🚀

profile
Data Expert 가 되고싶은 사람 | Thoughts Become Things. 할 수 있다고 생각하면 할 수 있다. 할 수 없다고 생각하면 할 수 없다. | www.linkedin.com/in/명수-제-7ab843200

0개의 댓글