만약에 오늘 들어온 데이터만 봐야할 경우
혹은 어제부터 오늘 전 까지의 데이터만 봐야하는 경우 와 같은
해당날의 모든 날 마지막 시간까지 체크를 해야할때
아래와 같이 다음날 전을 포함하지 않는 방식으로 많이 처리를 합니다
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를 더해준다!
'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 |
댓글