본문 바로가기

IT/Oracle

SQL 날짜 관련 함수 Query


우선 문제! 결과 값이 다른 보기는? (정답과 풀이는 맨 아래에..)

1. select to_date(to_date('20151231 115900','YYYYMMDDHH24MISS')) + 1/24 from dual;

2. select round(to_date('20151231115900','YYYYMMDDHH24MISS'),'DD') + 1/24 from dual;

3. select round(to_date('20151231115900','YYYYMMDDHH24MISS'),'DAY') + 1/24 from dual;

4. select trunc(to_date('20151231115900','YYYYMMDDHH24MISS')) + 1/24 from dual; 



DATE 함수의 FORMAT 문자열

- YYYY, YYY, YY, Y, YEAR: 년도의 첫날 (7월 1일부터 반올림)

- Q: 분기의 첫날(분기의 두번째 달 16일부터 반올림)

- MONTH, MON, MM: 월의 첫날(16일부터 반올림)

- DDD, DD: 일(정오 12시를 지나면 반올림)

- DAY, DY, D: 주의 첫 요일(수요일 정오가 지나면 반올림)

- HH, HH12, HH24: 시단위

- MI: 분단위



* ADD_MONTHS(date, n) : date에 n달을 추가한다. date값을 반환하며 n은 정수이다.

* LAST_DAY(date) : date를 포함하는 달의 마지막 날을 반환, date값을 반환 한다.

* MONTHS_BETWEEN(date1, date2) : date1과 date2의 차이를 달 수로 표현, 정수를 반환하며 차이가 1개월 미만인 경우는 1보다 작은 소수를 반환한다.  즉 (date1 – date2)를 나타낸 것이라고 생각하면 된다.

* NEXT_DAY(date, c) : 날짜 date를 포함해서 이후 나타나는 첫번째 c요일을 반환 한다.

* SYSTIMESTAMP : 오라클 9i에서 추가 되었으며 SYSDATE와 마찬가지로 해당 시스템의 현재 날짜 및 시간을 반환 한다. TIMESTAMP는 DATETIME의 확장이며 보다 정교한 시간을 나타낼 수 있다.


* ROUND(date, fmt) : date를 지정한 포맷 형식에 맞춰 표시하는데 반올림 한다.

* TRUNC(date, fmt) : date를 지정한 포맷 형식에 맞춰 표시하는데 절삭 한다.



* 현재 시스템의 시간 및 날짜를 확인

SQL> select sysdate, systimestamp from dual;

SYSDATE            SYSTIMESTAMP

------------    ---------------------------

03/10/01           03/10/01 10:52:28.243000 +09:00


 “2003년12월1일”에 3개월을 더하면 어떤 결과가 나올까?

SQL> select add_months('03/12/01', 3) ADD_MON from dual;

ADD_MON

--------

04/03/01 


 “2003년10월1일을 포함하는 달의 마지막 날을 반환 하는 예문 이다.

SQL> select last_day('03/10/01') LAST_DAY from dual;

LAST_DAY

--------

03/10/31        


SQL> select months_between('04/01/01','05/01/01') from dual;

MONTHS_BETWEEN('04/01/01','05/01/01')

-------------------------------------

-12


SQL> select months_between('04/01/01','05/01/30') from dual;

MONTHS_BETWEEN('04/01/01','05/01/30')

-------------------------------------

-12.935484


 “2003년 10월1일을 포함하여 다음 일요일을 구하는 예문이다.

SQL> select next_day('03/10/01','일요일')from dual;

NEXT_DAY

--------

03/10/05


  SYSDATE를 그냥 출력하면 날짜만 나오게 된다. 만약 시간도 확인을 하기 위해서는 to_char 와 같은 변환 함수를 이용하여 문자로 변환을 시켜 줘야 한다.

SQL> select sysdate, to_char(sysdate,'yyyy.mm.dd hh24:mi:ss') from dual;

SYSDATE  TO_CHAR(SYSDATE,'YY

--------    -------------------

04/02/17  2004.02.17 15:25:53


 현재 날짜를 2004년2월17일 오후15시25분 정도라면 가정 하고 다음 예문을 이해 하자. MONTH는 월의 첫날을 출력하는데 17일 이므로 월은 반올림 하면 다음 월인 3월1일이 출력된다. 또한 DAY의 경우 주의 첫요일을 출력하는데 2월17일은 화요일 이므로 반올림 대상이 아니다. 즉 주의 첫요일인 2월15일이 출력 되는 것이다.


SQL> select round(sysdate, 'MONTH'), round(sysdate, 'DAY') from dual;

ROUND(SY ROUND(SY

-------- --------

04/03/01 04/02/15


 EMP 테이블에서 “SMITH” 사원의 오늘(2004년2월17일 이라고 가정)을 기준으로 입사한지 몇 개월째 인지 파악 하려고 한다.(16째일 부터는 1개월로 반올림하는 예문이다.)


SQL> select ename, hiredate "입사일", sysdate "기준일",

  2             round(months_between(sysdate, hiredate), 0) "입사개월수"

  3      from emp

  4    where ename = 'SMITH';


ENAME      입사일   기준일   입사개월수

---------- -------- -------- ----------

SMITH      80/12/17 04/02/17        278


 아래는 trunc를 사용하는 예문이다. 위의 예문에서는 현재 날짜가 17일 이므로 반올림이 되었지만 절삭을 하면 월의 첫날은 2월1일이 된다.


SQL> select trunc(sysdate, 'MONTH'), trunc(sysdate, 'DAY') from dual;

TRUNC(SY TRUNC(SY

-------- --------

04/02/01 04/02/15


 일단위로 보면 정오를 지났으므로 일자가 반올림 된다.

SQL> select round(sysdate, 'DD') from dual;

ROUND(SY

--------

04/02/18


* 아래 예문은 1970년 1월1일부터 오늘까지의 일수차이를 반환하는 예문이다.

SQL> select TRUNC(SYSDATE-TO_DATE('19700101','YYYYMMDD')) AS 일수차이 from dual;

일수차이

----------

 12466



[날짜 산술 연산] 

date + number = date

date – number = date

date – date = 정수

date + number/24 = date





정답: 3번

1. select to_date(to_date('20151231 115900','YYYYMMDDHH24MISS')) + 1/24 from dual; 

  => 2015-12-31 오전 1:00:00

2. select round(to_date('20151231115900','YYYYMMDDHH24MISS'),'DD') + 1/24 from dual;

  => 2015-12-31 오전 1:00:00

3. select round(to_date('20151231115900','YYYYMMDDHH24MISS'),'DAY') + 1/24 from dual;

  => 2016-01-03 오전 1:00:00

4. select trunc(to_date('20151231115900','YYYYMMDDHH24MISS')) + 1/24 from dual; 

  => 2015-12-31 오전 1:00:00

 문제를 맞추기 위해선 ROUND와 TRUNC의 차이점과

 일(DD)와 날짜(DAY)를 언제 반올림 하는지 정확히 인지하고 있어야 한다.

 2번같은 경우에는 2015/12/31 11:59분이므로 12시(정오)를 넘지 않았으므로 반올림하지 않는다, =>그대로 출력

 3번은 2015/12/31 즉 목요일이다. 수요일 정오가 지났으므로 반올림한다. 그러므로 2016/01/03일 일요일 출력

 3번의 이해를 돕기 위해서 만약.. 날짜를 '20151229115900' 바꾸면 결과가 어떻게 출력될까?

 한 주의 첫요일은 일요일이니까 반올림이 안되서 그 날의 일요일 2015-12-27 오전 1:00:00 이 출력됨.