상세 컨텐츠

본문 제목

SQL 쿼리 날짜 차이 구하기 datediff 사용하는 방법

IT/DB

by JR 2025. 7. 14. 20:08

본문

300x250
반응형

 

 

 

아래 쿼리 1,2번 뜻과 차이점은?

 

1. datediff(ymdt_1,lag(ymdt_1,1) over (order by ymdt_1) as 경과일수_A

2. datediff(ymdt_1,lag(ymdt_1,1) over (partition by seq by ymdt_1) as 경과일수_B

 

 

주신 두 SQL 구문은 DATEDIFF와 LAG 윈도우 함수를 사용해서 날짜 간 차이, 즉 경과일수를 구하는 용도인데요.

 

둘 다 유사해 보이지만 PARTITION BY의 유무에 따라 중요한 차이가 생깁니다.

 


✅ 먼저 각 쿼리의 기본 구조

1. 경과일수_A

DATEDIFF(ymdt_1, LAG(ymdt_1, 1) OVER (ORDER BY ymdt_1)) AS 경과일수_A

 
  • 전체 데이터를 대상으로 ymdt_1을 정렬하고, 바로 이전 날짜와의 차이를 계산합니다.
  • 전 행과의 날짜 차이를 계산 (전 행이 어떤 사용자든, 어떤 그룹이든 상관 없음)

2. 경과일수_B

DATEDIFF(ymdt_1, LAG(ymdt_1, 1) OVER (PARTITION BY seq ORDER BY ymdt_1)) AS 경과일수_B
  • seq 기준으로 그룹을 나눈 뒤, 각 그룹 내에서 ymdt_1을 정렬해서 이전 날짜와의 차이를 구합니다.
  • 즉, 그룹(=seq별 묶음) 내부에서만 이전 값과 비교

🔍 차이점 정리

 

항목 경과일수_A(1번) 경과일수_B (2번)
비교 기준 전체 행 기준 seq별 그룹 기준
이전 값(LAG) 전체 행에서 바로 앞에 있는 ymdt_1 같은 seq 값 안에서 앞에 있는 ymdt_1
용도 예시 전체 연속적인 날짜 간격 확인 사용자별, 그룹별, 카테고리별 날짜 간격 분석
첫 행 결과 전체 첫 행은 NULL 각 seq별 첫 행은 NULL
 

📌 예시로 비교해 보기

 

-- 예시 데이터
seq   | ymdt_1
------|------------
A     | 2024-01-01
A     | 2024-01-05
A     | 2024-01-10
B     | 2024-01-02
B     | 2024-01-06
 

➤ 경과일수_A (전체 순서 기준)

정렬 기준은 ymdt_1, 그룹 나눔 없음

 

seq ymdt_1 LAG(ymdt_1) 경과일수_A
A 2024-01-01 NULL NULL
B 2024-01-02 2024-01-01 1
A 2024-01-05 2024-01-02 3
B 2024-01-06 2024-01-05 1
A 2024-01-10 2024-01-06 4
 

➤ 경과일수_B (seq 그룹별)

그룹 seq 기준으로 내부 정렬 후 이전값과 비교

seq ymdt_1 LAG(ymdt_1) 경과일수_B
A 2024-01-01 NULL NULL
A 2024-01-05 2024-01-01 4
A 2024-01-10 2024-01-05 5
B 2024-01-02 NULL NULL
B 2024-01-06 2024-01-02 4
 

✅ 결론

  • 경과일수_A: 전체 데이터에서 날짜 흐름을 따라 이전 날짜와 비교
  • 경과일수_B: **그룹별(예: 사용자, 주문ID 등)**로 이전 날짜와 비교
  • 일반적으로 사용자별 활동일수, 주문 간격, 방문 주기 분석에는 PARTITION BY를 씁니다.

 

 

✅ 질문 요약

 
DATEDIFF(ymdt_1, LAG(ymdt_1, 1) OVER (PARTITION BY seq) AS 경과일수_B

 

 

여기서 ORDER BY 없이 PARTITION BY seq만 사용하는 것이 가능한지 → 가능은 하지만 거의 무의미하며, 실질적인 결과가 보장되지 않습니다.


🔍 SQL 윈도우 함수에서 ORDER BY는 어떤 역할?

  • LAG() 함수는 **"지정된 순서대로 행을 비교"**할 때 의미가 있습니다.
  • ORDER BY가 없으면, DB 엔진은 어떤 기준으로 "이전 행"을 선택할지 모릅니다 → 결과는 **비결정적(예측 불가)**입니다.

 

❌ 다음은 비권장

LAG(ymdt_1) OVER (PARTITION BY seq)
 
  • 사용자별로는 나누지만, 날짜순인지, 랜덤순인지, 입력순인지 알 수 없음
  • 어떤 행이 LAG() 대상이 될지 DB마다 다를 수 있고, 실행마다 바뀔 수도 있음

✅ 반드시 ORDER BY를 명시하세요

sql
 
LAG(ymdt_1) OVER (PARTITION BY seq ORDER BY ymdt_1)
 
 

이렇게 해야 사용자별로 날짜 순으로 정렬한 후, 바로 이전 날짜와의 차이를 올바르게 구할 수 있습니다.


🧪 정리 요약

구문 실행 가능 여부 설명
LAG(...) OVER (PARTITION BY seq) ✅ 가능하지만 ⚠️ 권장되지 않음 이전 행이 어떤 것인지 불명확
LAG(...) OVER (PARTITION BY seq ORDER BY ymdt_1) 권장 사용자별로 날짜순으로 정확한 이전 날짜를 지정
 

✅ 최종 추천 쿼리

DATEDIFF( ymdt_1, LAG(ymdt_1, 1) OVER (PARTITION BY seq ORDER BY ymdt_1) ) AS 경과일수_B
 
 
 
 
 
 

 

300x250
반응형

관련글 더보기