database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 40854 게시물 읽기
No. 40854
특정일자에서 3.5개월전의 날짜를 어떻게 구할 수 있는지요?
작성자
김종훈(팔공산까치)
작성일
2015-07-09 09:48ⓒ
2015-07-09 09:49ⓜ
조회수
8,441

 ADD_MONTHS 는 3개월, 4개월전은 구할 수 있던데 

-3.5 개월전은 어떻게 구하는지 한수 가르침 부탁드립니다.

 

감사합니다.

이 글에 대한 댓글이 총 3건 있습니다.

-- 0.5 개월을 통상 보름(15일)이라 치고
SELECT ADD_MONTHS(sysdate, -3) - 15 FROM dual;

마농(manon94)님이 2015-07-09 10:22에 작성한 댓글입니다.

 마농님 감사합니다.

김종훈(팔공산까치)님이 2015-07-09 11:10에 작성한 댓글입니다.

 이 문제는 저도 관심이 있어서 과거에 테스트했던 것입니다.

김종훈님께서는 문제를 해결하셔서 축하드리지만

만약 months_between 의 역함수를 구하고 싶은 것이 원래의 요건이라면

다른 해결 방법이 필요합니다.

 

months_between 은 실수를 리턴하고 이 실수를 그대로 add_months에 넣어도 원래의 날짜를 구할 수는 없습니다.

그 이유는 add_months가 정수를 받기 때문이죠.

 

그러면 완전한 months_between의 역함수는 어떻게 구할까요...

 

아래의 SQL은 오라클의 months_between의 원래 로직을 SQL로 구현하고 그 역함수를 SQL로 구현한 것입니다.

 

참고가 되시기를 바랍니다.

select
    a.dt_base
    , a.dt
    , a.months
    , a.days
    , a.mms
    , a.my_months
    , a.bias
    , a.day_part
    , a.my_add_months
from
    (
        select
            a.dt_base
            , a.dt
            , a.months
            , a.days
            , a.mms
            , a.my_months
            , 31 - to_number(to_char(last_day(add_months(a.dt_base,trunc(a.months))),'dd')) bias
            , ((a.months - trunc(a.months)) * 31) day_part
            , case when to_char(add_months(a.dt_base,trunc(a.months)),'yyyymm') != to_char((add_months(a.dt_base,trunc(a.months)) + ((a.months - trunc(a.months)) * 31)),'yyyymm') then
                add_months(a.dt_base,trunc(a.months)) + ((a.months - trunc(a.months)) * 31) - (31 - to_number(to_char(last_day(add_months(a.dt_base,trunc(a.months))),'dd')))
            else 
                add_months(a.dt_base,trunc(a.months)) + ((a.months - trunc(a.months)) * 31)
            end my_add_months
        from
            (
                select
                    a.dt_base
                    , a.dt
                    , a.months
                    , a.days
                    , a.mms
                    , mms + days / 31 my_months
                from
                    (
                        select
                            a.dt_base
                            , a.dt
                            , a.months
                            , case when to_char(a.dt_base,'dd') > to_char(a.dt,'dd') then
                                31 - to_number(to_char(a.dt_base,'dd')) + to_number(to_char(a.dt,'dd'))
                            else
                                to_number(to_char(a.dt,'dd')) - to_number(to_char(a.dt_base,'dd'))
                            end days
                            , case when to_char(a.dt_base,'dd') > to_char(a.dt,'dd') then
                                ( to_number(to_char(a.dt,'yyyy')) * 12 + to_number(to_char(a.dt,'mm')) )
                                -
                                ( to_number(to_char(a.dt_base,'yyyy')) * 12 + to_number(to_char(a.dt_base,'mm')) )
                                - 1
                            else
                                ( to_number(to_char(a.dt,'yyyy')) * 12 + to_number(to_char(a.dt,'mm')) )
                                -
                                ( to_number(to_char(a.dt_base,'yyyy')) * 12 + to_number(to_char(a.dt_base,'mm')) )
                            end mms
                        from
                            (
                                select
                                    dt_base
                                    ,dt
                                    , months_between(dt,dt_base) months
                                from
                                    (
                                        select
                                            trunc(sysdate,'dd') dt_base
                                            , trunc(sysdate,'dd') + level - 1 dt
                                        from    dual
                                        connect by level < 36500
                                    ) a
                            ) a
                    )a
            ) a
    ) a
where   a.dt != a.my_add_months
김흥수(protokhs)님이 2015-07-10 11:29에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
40857초당 쿼리수 [1]
dba
2015-07-13
7174
40856union all 관련 여쭤봅니다. [1]
궁금
2015-07-10
7015
40855JDBC 라이브러리 지원버전
초보초보
2015-07-10
7100
40854특정일자에서 3.5개월전의 날짜를 어떻게 구할 수 있는지요? [3]
김종훈
2015-07-09
8441
40853시작일자/종료일자를 가지고 그 사이 날짜 다 뽑아낼려면... [1]
초보
2015-07-08
7700
40852질문좀 드려봐요(설문조사 통계 데이터) [2]
염진호
2015-07-08
7532
40851주차 관련해 질문있습니다. [1]
ORACLE
2015-07-08
7300
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.019초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다