-- 설득력이 떨어지는 질문인데요. -- 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 ) ) ;
-- 살짝 보완했습니다. 무조건 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 ) ) ;