데이터베이스 연구실.log

날짜와 시간

날짜 연산과 MONTHS_BETWEEN, ADD_MONTHS, NEXT_DAY, LAST_DAY 날짜 함수, INTERVAL 리터럴, 두 자리 연도 형식 RR과 YY의 차이, 세션 날짜 형식

SYSDATEMONTHS_BETWEENADD_MONTHSNEXT_DAYLAST_DAYINTERVALEXTRACTRRYYNLS_DATE_FORMATTIMESTAMP

#핵심 요약

SYSDATE는 오늘 날짜임
날짜에 숫자를 더하면 그만큼의 일수가 더해지고, 날짜끼리 빼면 일수가 나옴

MONTHS_BETWEEN(최신 날짜, 예전 날짜)는 개월 수, ADD_MONTHS(날짜, n)는 n개월 뒤, NEXT_DAY(날짜, '요일')는 그 뒤 첫 요일, LAST_DAY(날짜)는 그 달의 마지막 날임

두 자리 연도를 YY로 해석하면 항상 현재 연도와 같은 세기가 됨
RR은 지정한 두 자리와 현재 연도의 끝 두 자리에 따라 세기가 달라짐

날짜 문자열 비교는 세션의 NLS_DATE_FORMAT에 따라 결과가 달라짐

#개념과 동작 원리

RR 해석 규칙:

지정한 두 자리 연도 현재 연도 끝 두 자리 00~49 현재 연도 끝 두 자리 50~99
00~49 현재와 같은 세기 현재 세기 + 1
50~99 현재 세기 - 1 현재와 같은 세기

그래서 현재 연도가 20xx 전반(00~49)이면 RR로 81은 1981, 25는 2025임
YY로는 81도 2081이 됨
실습에서 세션 형식을 YY/MM/DD로 바꾸자 hiredate = '81/11/17'이 조회되지 않은 이유가 이것임

MONTHS_BETWEEN(date1, date2): date1이 더 나중이면 양수, 더 이르면 음수임
두 날짜의 일(日)이 같거나 둘 다 그 달의 마지막 날이면 결과는 정수임
그 밖에는 소수가 나올 수 있어 실습에서는 ROUND로 감쌌음

ADD_MONTHS: 결과 타입은 항상 DATE임
날짜가 그 달의 마지막 날이거나, 결과 달의 일수가 원래 일보다 적으면 결과 달의 마지막 날이 됨

NEXT_DAY: 요일 이름은 세션 날짜 언어의 전체 이름이나 약어여야 함
수업 자료처럼 '월요일'은 한국어 날짜 언어 세션에서 쓰는 형태임

INTERVAL 필드 범위:

필드 범위
YEAR, DAY 정수, 제한 없음
MONTH 0~11
HOUR 0~23
MINUTE 0~59
SECOND 0~59.9(N), N은 소수 자릿수

실습에서는 INTERVAL YEAR TO MONTH는 년과 월만, INTERVAL DAY TO SECOND는 일부터 초까지 담는다는 점을 OCP 문제로 설명했음
일수 기준 이자 계산처럼 일 단위가 필요하면 DAY TO SECOND를 고른다는 것이 실습의 결론임

#필수 명령어 또는 SQL

#세션 날짜 형식

SQL Developer 또는 SQL*Plus조회만 함
SELECT * FROM nls_session_parameters;
SQL Developer 또는 SQL*Plus현재 세션 설정만 변경함
ALTER SESSION SET nls_date_format = 'YY/MM/DD';

결과 해석: 바꾼 뒤 WHERE hiredate = '81/11/17'은 문자열이 2081년으로 해석되어 1981년 입사자와 맞지 않음
'RR/MM/DD'로 되돌리면 다시 조회됨
세션 설정은 그 세션에만 적용됨

#날짜 연산과 날짜 함수

SQL Developer 또는 SQL*Plus조회만 함
SELECT SYSDATE FROM dual;

SELECT ename, ROUND(SYSDATE - hiredate)
  FROM emp;

SELECT ename, ROUND(MONTHS_BETWEEN(SYSDATE, hiredate))
  FROM emp;

SELECT SYSDATE + 100,
       ADD_MONTHS(SYSDATE, 100),
       SYSDATE + (INTERVAL '100' MONTH)
  FROM dual;

SELECT NEXT_DAY(TO_DATE('2025/06/03', 'RRRR/MM/DD'), '월요일'),
       LAST_DAY(TO_DATE('2025/06/03', 'RRRR/MM/DD'))
  FROM dual;

결과 해석:

실습에서는 ADD_MONTHS('2025/06/03', 100)처럼 문자열을 그대로 넣는 문장도 같이 보였음
이 문장은 문자열이 세션 날짜 형식으로 암시적 변환될 때만 동작함
TO_DATE로 형식을 지정하는 편이 안전함(형 변환과 날짜 포맷)

실습 업무 문제(답 확인 불가): 계약 만료일(입사 후 100개월), 대출 만기일(오늘부터 36개월), 적금 만기일과 남은 일수(24개월), 다음 수요일 배송 완료일, 30일 뒤 가장 가까운 토요일 마감일, 카드 결제일(이번 달과 다음 달 말일), 이번 달 말일까지 남은 일수

#날짜에서 부분 꺼내기와 INTERVAL

실습 속성 메모에 있는 형태:

SQL Developer 또는 SQL*Plus조회만 함
SELECT EXTRACT(YEAR FROM hiredate) FROM emp;

SELECT TO_YMINTERVAL('01-02'),
       TO_DSINTERVAL('100 10:00:00'),
       INTERVAL '1-6' YEAR TO MONTH,
       INTERVAL '2 04:30:00' DAY TO SECOND
  FROM dual;

결과 해석: 개별 실행 출력은 기재 없음

#PostgreSQL 비교

PostgreSQL조회만 함
SELECT EXTRACT(YEAR FROM AGE(NOW(), hiredate)) * 12
     + EXTRACT(MONTH FROM AGE(NOW(), hiredate))
  FROM emp;

SELECT ename, hiredate, hiredate + (INTERVAL '100' MONTH) "계약 만료일"
  FROM emp;

결과 해석:

설명: AGE의 MONTH는 전체 개월 수가 아니라 년을 뺀 나머지 월이어서 YEAR * 12와 더함
PostgreSQL에는 LAST_DAY가 없어 실습에서는 DATE_TRUNC('month', $1) + INTERVAL '1 month - 1 day'로 함수를 만들어 썼음
다음 수요일은 EXTRACT(DOW FROM current_date)(일요일 0 ~ 토요일 6)로 계산했음

#사용 조건과 주의사항

NEXT_DAY의 요일 이름은 세션 언어에 따라 바꿔야 함

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기