날짜계산 질문 드립니다. 2 5 5,091

by 보일듯말듯 [2013.01.31 16:05:34]


20130128_133934.jpg (11,353Bytes)

보통 1달은 30일로 잡고 계산을 하는데요 

2013-01-20 의 1개월은 2013-02-20 이 아닌 -1을 해서 2013-02-19 이렇게 계산을 합니다.


근데 2월이 문제인지라 

 시작일 종료일
2013-01-29 ~ 2013-02-28    1개월    0일
2013-01-30 ~ 2013-02-28    1개월    0일
2013-01-31 ~ 2013-02-28    1개월    0일


이렇게 나오는게 가능 할까요?

by 부쉬맨 [2013.01.31 16:56:03]
가능은하겠죠
if 로 윤달? 일때만 저렇게 계산하면될꺼니깐..

by 신이만든짝퉁 [2013.01.31 17:55:59]
  select sysdate "현재", add_months(sysdate,1) "1개월 뒤",
        add_months(sysdate,2) "2개월 뒤", add_months(sysdate,3) "3개월 뒤"
  from dual;


현재                            1개월 뒤                         2개월 뒤                     3개월 뒤
-------------------------------- -------------------------------- -------------------------------- --------------------------------
2013/01/31                       2013/02/28                       2013/03/31                       2013/04/30

이렇게 처리하시는 건 어떠세요?

by 마농 [2013.01.31 18:20:49]
-- 설득력이 떨어지는 질문인데요.
-- 2월1일 부터 2월말일까지가 분명 1개월 일텐데.
-- 거기에 1월 마지막 몇일이 추가되는데도 0일로 계산하면 이상할듯 합니다.
-- 제 생각에는 다른 접근 방법을 갖는 것이 좋을 것 같습니다.
-- 시작일과 종료일 사이에 온전한 월만 빼서 개월수 산정하고
-- 앞뒤 잘리는 월에 대해서는 각각 일수 계산하여 합치는 방식은 어떨런지요?
-- 예를 들면 1월 20일부터 5월 5일까지라면?
-- 2월, 3월, 4월은 온전한 월이므로 3개월
-- 1월(20~31) 12일 + 5월(1~5) 5일 = 17일
-- 결과는 3개월 17일
-- 만약 앞뒤 일수 합산결과가 31 일이 넘으면
-- 개월수에는 1 더하고 일수에서는 31 빼는 방식으로...
-- 제가 제시한 방식을 한번 고려해 보세요.

WITH t AS
(
SELECT '20130120' sdt, '20130505' edt FROM dual
UNION ALL SELECT '20130120', '20130131' FROM dual
UNION ALL SELECT '20130101', '20130228' FROM dual
UNION ALL SELECT '20121202', '20130130' FROM dual
UNION ALL SELECT '20130129', '20130228' FROM dual
UNION ALL SELECT '20130130', '20130228' FROM dual
UNION ALL SELECT '20130131', '20130228' FROM dual
UNION ALL SELECT '20130201', '20130228' FROM dual
)
SELECT sdt, edt
     , m + FLOOR((d1 + d2) / 31) mm
     , MOD(d1 + d2, 31) dd
     , m, d1, d2
  FROM (SELECT sdt, edt
             , GREATEST(0, MONTHS_BETWEEN(TRUNC(edt+1, 'mm'), LAST_DAY(sdt-1)+1)) m
             , LAST_DAY(sdt-1) - sdt + 1 d1
             , edt - TRUNC(edt+1, 'mm') + 1 d2
          FROM (SELECT TO_DATE(sdt, 'yyyymmdd') sdt
                     , TO_DATE(edt, 'yyyymmdd') edt
                  FROM t
                )
        )
;

by 마농 [2013.01.31 18:30:15]
-- 살짝 보완했습니다. 무조건 31일로 나누는게 아니고.
-- 시작일의 마지막 일자로 나누는걸로 했습니다.
WITH t AS
(
SELECT '20130120' sdt, '20130505' edt FROM dual
UNION ALL SELECT '20130120', '20130131' FROM dual
UNION ALL SELECT '20130101', '20130228' FROM dual
UNION ALL SELECT '20121202', '20130130' FROM dual
UNION ALL SELECT '20130129', '20130228' FROM dual
UNION ALL SELECT '20130130', '20130228' FROM dual
UNION ALL SELECT '20130131', '20130228' FROM dual
UNION ALL SELECT '20130201', '20130228' FROM dual
UNION ALL SELECT '20130202', '20130401' FROM dual
)
SELECT sdt, edt
     , m + FLOOR((d1 + d2) / d3) mm
     , MOD(d1 + d2, d3) dd
     , m, d1, d2, d3
  FROM (SELECT sdt, edt
             , GREATEST(0, MONTHS_BETWEEN(TRUNC(edt+1, 'mm'), LAST_DAY(sdt-1)+1)) m
             , LAST_DAY(sdt-1) - sdt + 1 d1
             , edt - TRUNC(edt+1, 'mm') + 1 d2
             , TO_CHAR(LAST_DAY(sdt-1), 'dd') d3
          FROM (SELECT TO_DATE(sdt, 'yyyymmdd') sdt
                     , TO_DATE(edt, 'yyyymmdd') edt
                  FROM t
                )
        )
;

by Oracler [2013.01.31 22:39:36]
1월 20일부터 30일을 계산하면 2월 19일이 아니라 2월 18일입니다. 1월은 31일까지 있으니까요.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입