입력결과에 따라 출력 결과 가능 할까요 ? 0 4 2,533

by 유정완 [SQL Query] [2011.07.22 16:31:49]


with t as (
select
    '111' no
,  TO_DATE('20091001','YYYYMMDD') start_day
,  TO_DATE('20120301','YYYYMMDD') end_day
  from  dual
  union  all
select
    '222' no
,  TO_DATE('20081001','YYYYMMDD') start_day
,  TO_DATE('20120301','YYYYMMDD') end_day
  from  dual
)
select * from  t
;

입력

NO   START_DAY      END_DAY
111  2009-10-01 00:00:00   2012-03-01 00:00:00
222  2008-10-01 00:00:00   2012-03-01 00:00:00

결과
111 2009-10-01 00:00:00 2009-12-31 00:00:00
111 2010-01-01 00:00:00 2010-12-31 00:00:00
111 2011-01-01 00:00:00 2011-12-31 00:00:00
111 2012-01-01 00:00:00 2012-03-01 00:00:00
222 2008-10-01 00:00:00 2008-12-31 00:00:00
222 2009-01-01 00:00:00 2009-12-31 00:00:00
222 2010-01-01 00:00:00 2010-12-31 00:00:00
222 2011-01-01 00:00:00 2011-12-31 00:00:00
222 2012-01-01 00:00:00 2012-03-01 00:00:00
입력에 따라 출력결과 가능 할까요  ?


by 마농 [2011.07.22 17:31:35]
WITH t AS
(
SELECT 111 no
, TO_DATE('20091001', 'yyyymmdd') start_day
, TO_DATE('20120301', 'yyyymmdd') end_day
FROM dual
UNION ALL
SELECT 222 no
, TO_DATE('20081001', 'yyyymmdd') start_day
, TO_DATE('20120301', 'yyyymmdd') end_day
FROM dual
)
SELECT no
, GREATEST(start_day, ADD_MONTHS(TRUNC(start_day, 'yy'), (lv-1)*12)) start_day
, LEAST(end_day, ADD_MONTHS(TRUNC(start_day, 'yy'), lv*12)-1) end_day
FROM t
, (SELECT level lv FROM dual CONNECT BY level <= 9)
WHERE lv <= TO_CHAR(end_day, 'yyyy') - TO_CHAR(start_day, 'yyyy') + 1
ORDER BY no, lv
;

by 유정완 [2011.07.22 18:10:50]
마농님 감사 합니다!!
level <= 9는 data가 9개 나오니깐 9로 fix 시켰는데
TO_DATE('20061001','YYYYMMDD') data가 바뀌면 10로 또 바꾸어 주어합니다 9라는 숫자대신 start_day - end_day 뺀 숫자로 대체 할 수 있나요
결론 level <= 9 (9대신 로직 써서 가능 할까요)


by 유정완 [2011.07.22 18:15:05]

WHERE lv <= TO_CHAR(end_day, 'yyyy') - TO_CHAR(start_day, 'yyyy') + 1
로직 있네요 잘 됩니다 감사합니다!!!

by 마농 [2011.07.23 09:43:43]
굳이 복잡한 로직 넣으실 필요 없습니다.
9년이상 자료가 없다면 그냥 9 로 하시면 되구요.
넉넉하게 더 큰 숫자 주셔도 됩니다.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입