본문 바로가기
2.2 DB/ORACLE

[Oracle/SQL] 날짜 마지막 시간 적용에 0.99999 쓰는 이유

by Dohi._. 2024. 9. 25.
728x90

만약에 오늘 들어온 데이터만 봐야할 경우

혹은 어제부터 오늘 전 까지의 데이터만 봐야하는 경우 와 같은

 

해당날의 모든 날 마지막 시간까지 체크를 해야할때

아래와 같이 다음날 전을 포함하지 않는 방식으로 많이 처리를 합니다

WHERE  날짜 >= TRUNC(sysdate)
  AND  날짜 <  TRUNC(sysdate) + 1

 

이렇게 설계를 하시는 경우도 있지만

간혹 이렇게 하는 경우도 있습니다

WHERE  날짜 BETWEEN TRUNC(sysdate) AND TRUNC(sysdate) + 0.99999

이 0.99999는 뭘까요?

 

위에서는 1을 더했는데

왜 아래에선 1을 안더하고 0.99999를 더했을까요

 

BETWEEN은 포함하는 개념이기 때문에 +1을 더했다면

다음날의 00시00분00초의 데이터까지 불러왔을겁니다.

 

 

근데 왜 0.99999를 더할까요

빠른 이해를 위해서
한번 아래 코드를 돌려보겠습니다

SELECT   TRUNC(sysdate)                            AS 오늘
       , TRUNC(sysdate) + 1                        AS 내일
       , TRUNC(sysdate) - 1                        AS 어제    
       , TRUNC(sysdate) + 0.99999                  AS 언제일까
       , TO_DATE('20240925', 'YYYYMMDD') + 0.99999 AS 언제일까요
  FROM dual
;

 

아! 0.99999를 더하면 23:59:59가 더해지는 것을 알 수 있습니다

왜 0.99999일까요 다른것도 한번 돌려보겠습니다.

 

테스트을 위해서 0.9~0.999999 까지 한번 다 돌려봤는데요

SELECT   TRUNC(sysdate)
       , TRUNC(sysdate) + 0.9
       , TRUNC(sysdate) + 0.99
       , TRUNC(sysdate) + 0.999
       , TRUNC(sysdate) + 0.9999
       , TRUNC(sysdate) + 0.99999
       , TRUNC(sysdate) + 0.999999
  FROM dual
;

.. 테스트를 해봐도
0.99999만 정상적인 것을 알 수 있다 

 

사유는 다음과 같은데요
Oracle에서 + 1 을 하면 다음 하루를 나타냅니다


날짜는 초단위로 계산이 되기 때문에 1은 86400초를 더한 개념입니다.

그래서 +1 한건 초단위개념에서는 86400초를 더한것!

 

그럼  0.99999 의 경우로 보면

86,400 * 99999 / 100,000 =86,399.136 로 나오는데
즉, 다음날까지 1초 차이의 숫자이이기 때문에

23:59:59가 더해지는 겁니다.

 

그럼 0.999999는..?

 

0.999999의 경우는 86,399.913 초로

뒤의 숫자가 반올림되어 하루가 된다(86400로 반올림)

 

아래의 사진은 반올림이 실제로 기준을 나타낸다는 실험결과입니다.
0.999994는 23:59:59로 되는데 0.999995 부터 하루가 더해집니다.

둘의 차이는 소수점에 있고 각각 소수점 첫자리가 4 와 5로 끝납니다.

 

아 반올림으로 처리가 되는구나 

 

0.99999 (9가 5개!  사용하려면 5개라는 점을 지켜주자)

 


아래는

실제사용 예제와

주로 나타나는 실수사례를 정리해봤습니다.

 

 

1. 0.99999를 사용안하고 당일 데이터만 보기

SELECT *
  FROM (
        SELECT TRUNC(sysdate)         AS 날짜  FROM DUAL
        UNION ALL
        SELECT TRUNC(sysdate)+0.99999 AS 날짜 FROM DUAL
        UNION ALL
        SELECT TRUNC(sysdate)+1       AS 날짜 FROM DUAL
        )
WHERE  날짜 >= TRUNC(sysdate)
        AND 날짜 < TRUNC(sysdate)+1
        ;

 

결과

2. 0.99999를 사용 했을때

 

SELECT *
  FROM (
        SELECT TRUNC(sysdate)         AS 날짜 FROM DUAL
        UNION ALL
        SELECT TRUNC(sysdate)+0.99999 AS 날짜 FROM DUAL
        UNION ALL
        SELECT TRUNC(sysdate)+1       AS 날짜 FROM DUAL
        )

 WHERE  날짜 BETWEEN TRUNC(sysdate)  AND TRUNC(sysdate) + 0.99999
;

결과

제가만든 프로그램으로 돌려봤어요:)..

 

둘다 결과가 동일함을 알수있다

 

 

실수사례

실수 1)

잘못된 BETWEEN

SELECT *
  FROM (
        SELECT TRUNC(sysdate)         AS 날짜  FROM DUAL
        UNION ALL
        SELECT TRUNC(sysdate)+0.99999 AS 날짜 FROM DUAL
        UNION ALL
        SELECT TRUNC(sysdate)+1       AS 날짜 FROM DUAL
        )

 WHERE 날짜 BETWEEN TO_DATE('20240925')  AND TO_DATE('20240926')
;

결과

 

실수 2)

잘못된 0.9999

SELECT *
  FROM (
        SELECT TRUNC(sysdate)         AS 날짜  FROM DUAL
        UNION ALL
        SELECT TRUNC(sysdate)+0.99999 AS 날짜 FROM DUAL
        UNION ALL
        SELECT TRUNC(sysdate)+1       AS 날짜 FROM DUAL
        )
    WHERE  날짜 BETWEEN TRUNC(sysdate) AND TRUNC(sysdate) + 0.9999
;

결과

제가만든 프로그램으로 돌려봤어요 ..:)

 

 

결론

0.99999는 23:59:59를 더해준다!

728x90

'2.2 DB > ORACLE' 카테고리의 다른 글

[oracle] Union / Union ALL  (0) 2024.09.30
[Oracle] null 처리 함수 (NVL, NVL2)  (0) 2024.09.26
[ORACLE] 테이블 복제  (0) 2024.09.23
[Oracle/SQL] With 절  (0) 2024.07.30
[Oracle/SQL] MERGE INTO  (0) 2024.07.30

댓글