본문 바로가기
[개발] Programming/Database

오라클 날짜 계산 방법과 예제 정리

by eatyourKimchi 2023. 11. 10.

 

 오라클에서 쿼리로 날짜를 연산하는 방법은 다양하지만, 

그중에서 쉽게 계산하고 비교할 수 있는 방법을 정리해 봤습니다.

 

 

 

01 오라클 현재 날짜, 시간

현재 날짜와 시간을 구하는 건 두 가지 방법이 있는데, 가장 흔하게 사용하는 건 SYSDATE 입니다.

결제나 예약처럼 밀리세컨드 단위까지 봐야 한다면, SYSTIMESTAMP를 사용하면 됩니다.

 

1
2
3
4
SELECT SYSTIMESTAMP
       SYSDATE
  FROM dual 
;
cs

 

 

현재 시간은 필요 없고, 날짜만 구하고 싶다면 형변환을 해주면 됩니다.

 

1
2
3
4
5
6
SELECT TO_CHAR(SYSDATE'YYYYMMDD'),   -- 20231110 으로 표시
       TO_CHAR(SYSDATE'YYYY.MM.DD'), -- 2023.11.10 으로 표시
       TO_CHAR(SYSDATE'YY.MM.DD'),   -- 23.11.10 으로 표시
       TO_CHAR(SYSDATE'YYYY.MM')     -- 2023.11 으로 표시
  FROM dual 
;
cs

 

 

 

02 오라클 날짜 연산 

간단한 날짜 연산은 SYSDATE 에서 ' +, - 숫자 '를 하는 형태입니다.

숫자가 정수이면 날짜를 더하거나 빼고, 소수점이면 시간, 분, 초를 더하거나 빼게 됩니다.

또한 sysdate는 초단위까지 나오기 때문에 날짜를 기준으로 WHERE 절을 구성한다면

TO_CHAR 로 형변환을 해주어야 합니다.

 

여기서 핵심은 DATE 타입에만 +/- 연산이 되고, CHAR 타입이면 수학적 연산이 이루어집니다.

즉, '20230101' + 100 을 한다면, 3개월이 지난날이 되는 게 아니라 그냥 20230201이 됩니다.

연산을 위해서는 TO_DATE로 변환을 해줘야 100을 더해도 3개월로 인식됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
SELECT SYSDATE AS 오늘, 
       TO_CHAR(SYSDATE'YYYY/MM/DD'AS 오늘,
       
       SYSDATE +1/24/60/60 AS "1초 후",
       SYSDATE +1/24/60 AS "1분 후",
       SYSDATE +1/24 AS "1시간 후",
       
       SYSDATE +1 AS "하루 후",
       TO_CHAR(SYSDATE +1'YYYY/MM/DD'AS "하루 후"
 
  FROM dual
;
cs

 

 

만약 TO_CHAR 없이 아래와 같은 쿼리를 구성한다면,

실행되는 시간의 시분초 까지 포함하여 쿼리가 돌겠죠?

 

1
2
3
4
5
6
7
8
9
10
11
-- 날짜 + 시분초까지 비교하는 경우
SELECT *
  FROM dual
 WHERE CREATE_DATE > SYSDATE -1
;
 
-- 날짜로만 비교하는 경우
SELECT *
  FROM dual
 WHERE CREATE_DATE > TO_CHAR(SYSDATE -1'YYYYMMDD')
;
cs

 

 

 

03 오라클 사이 일수 연산

마지막으로 어느 날부터 어느 날까지 일수 차이를 계산하고 싶을 때가 있는데,

DATE 타입이면 아래와 같이 간단하게 '-' 빼기 연산으로 가능합니다.

하지만, CHAR 형이면 수학적 연산이 이루어지겠죠? 이땐 형변환을 해줘야 합니다.

 

아래 예시로 CHAR 타입 날짜끼리 연산했을 때 문제를 확인할 수 있습니다.

 

1
2
3
4
5
6
7
SELECT SYSDATE +100 AS "100 일 후",
       (SYSDATE +100- (SYSDATEAS "A. 사이 일 수"
       (SYSDATE +100- TO_DATE('20231109''YYYYMMDD'AS "B. 사이 일 수",
       '20240218' - '20231001' AS "C. 사이 일 수"
       
  FROM dual
;
cs

 

 

A. 결과는 DATE 타입끼리의 연산이므로 깔끔하게 계산되지만,

B. 결과는 시분초가 함께 있는 날짜와, 그냥 날짜를 비교하면 초까지 계산되어 복잡해지겠죠?

기본적으로 TO_DATE 안에 데이터에 시분초 데이터가 없으면 00:00:00으로 인식됩니다.

이걸 전부 자르고 날짜만 비교하고 싶으면 아래와 같이 TRUNC()로 날려주면 됩니다. (A의 결과)

 

1
2
3
4
5
SELECT TRUNC(SYSDATE +100- TO_DATE('20231109''YYYYMMDD'AS "A. 사이 일 수"
       TO_DATE('20240218''YYYYMMDD'- TO_DATE('20231109''YYYYMMDD'AS "B. 사이 일 수",
       
  FROM dual
;
cs

 

 

마지막으로 스트링형 끼리 날짜를 비교하고 싶으면 B처럼 하면 됩니다.

 

 

 

 

댓글