안녕하세요
WITH T AS
(
SELECT 'A' AS NO ,'20130506' AS STA_YMD, '20160805' AS END_YMD FROM DUAL
UNION ALL
SELECT 'B','20100120' , '20110203' FROM DUAL
)
NO별로 날짜를 자고싶은데.. 어렵습니다 ㅠ..
이거를 아래처럼 년도별로 자르는 쿼리를 만들고싶습니다.
NO sta_ymd end_ymd
A 20130506 20131231
A 20140101 20141231
A 20150101 20151231
A 20160101 20160805
B 20100120 20101231
B 20110101 20110203
이렇게 가능할까요 ㅠㅠ? 어렵네요;;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | WITH T AS ( SELECT 'A' AS NO , '20130506' BIG_YMD, '20160805' END_YMD FROM DUAL UNION ALL SELECT 'B' AS NO , '20100120' BIG_YMD, '20110203' END_YMD FROM DUAL) SELECT * FROM ( SELECT NO , BYMD , EYMD , T2.RN , CASE WHEN RN = 0 THEN BYMD ELSE ADD_MONTHS(TRUNC(BYMD, 'YEAR' ), 12 * RN) END BYMD2 , CASE WHEN RN = PYEAR THEN EYMD ELSE ADD_MONTHS(TRUNC(BYMD, 'YEAR' ), 12 *(RN + 1)) - 1 END EYMD2 FROM ( SELECT NO , TO_DATE(BIG_YMD, 'YYYYMMDD' ) BYMD , TO_DATE(END_YMD, 'YYYYMMDD' ) EYMD , FLOOR(MONTHS_BETWEEN(TO_DATE(END_YMD, 'YYYYMMDD' ), TO_DATE(BIG_YMD, 'YYYYMMDD' )) / 12) PYEAR FROM T) T1 , ( SELECT LEVEL - 1 RN FROM DUAL CONNECT BY LEVEL <= 100) T2) -- 100년 이상 차이나는 경우는 없다고 가정함 WHERE BYMD2 >= BYMD AND EYMD2 <= EYMD ORDER BY NO ASC , BYMD2 ASC ; |
이렇게 해보세요
1 2 3 4 5 6 7 8 9 10 11 12 13 | WITH T AS ( SELECT 'A' AS NO , '20130506' AS STA_YMD, '20160805' AS END_YMD FROM DUAL UNION ALL SELECT 'B' , '20100120' , '20110203' FROM DUAL ) SELECT NO , GREATEST(STA_YMD,TO_CHAR(TO_NUMBER(SUBSTR(STA_YMD,1,4)) + LV - 1)|| '0101' ) STA_YMD , LEAST(END_YMD,TO_CHAR(TO_NUMBER(SUBSTR(STA_YMD,1,4)) + LV - 1)|| '1231' ) END_YMD FROM T ,( SELECT LEVEL LV FROM DUAL CONNECT BY LEVEL <= 100) WHERE TO_NUMBER(SUBSTR(END_YMD,1,4)) - TO_NUMBER(SUBSTR(STA_YMD,1,4)) + 1 >= LV ORDER BY 1,2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | WITH T AS ( SELECT 'A' AS NO , '20130506' AS STA_YMD, '20160805' AS END_YMD FROM DUAL UNION ALL SELECT 'B' , '20100120' , '20110203' FROM DUAL ) SELECT S. NO NO , CASE WHEN STA_YMD >= SUBSTR(STA_YMD,1,4)+D.LV-1|| '0101' AND STA_YMD < SUBSTR(STA_YMD,1,4)+D.LV|| '0101' THEN STA_YMD ELSE SUBSTR(STA_YMD,1,4)+D.LV-1|| '0101' END STA_YMD , CASE WHEN END_YMD > SUBSTR(STA_YMD,1,4)+D.LV-2|| '1231' AND END_YMD <= SUBSTR(STA_YMD,1,4)+D.LV-1|| '1231' THEN END_YMD ELSE SUBSTR(STA_YMD,1,4)+D.LV-1|| '1231' END END_YMD FROM T S ,( SELECT DISTINCT NO , LEVEL LV FROM T S CONNECT BY LEVEL <= (SUBSTR(S.END_YMD,1,4)-SUBSTR(S.STA_YMD,1,4)+1)) D WHERE 1=1 AND S. NO = D. NO ORDER BY NO , LV; |