기본 테이블 | |
날짜 | 수치 |
2020-05-01 | 1 |
2020-05-02 | 2 |
2020-05-03 | 3 |
2020-05-04 | 4 |
2020-05-05 | 5 |
2020-05-06 | 6 |
2020-05-07 | 7 |
2020-05-08 | 8 |
2020-05-09 | 9 |
2020-05-10 | 10 |
2020-05-11 | 11 |
2020-05-12 | 12 |
2020-05-13 | 13 |
2020-05-14 | 14 |
2020-05-15 | 15 |
2020-05-16 | 16 |
2020-05-17 | 17 |
2020-05-18 | 18 |
2020-05-19 | 19 |
2020-05-20 | 20 |
2020-05-21 | 21 |
비율 정보 테이블 | |
날짜 | 비율(%) |
2020-05-09 | 120 |
2020-05-19 | 200 |
테이블이 두 개가 있습니다.
1. 날짜와 그 에 해당하는 값이 들어있는 테이블
2. 보정이 일어나는 날짜와 필요한 비율이 들어있는 테이블
이 두 테이블을 기반으로 조회 기간에 따라 보정된 값이 보이는 뷰나 테이블을 만들고 싶습니다.
1. 보정이 일어나는 날은 값이 변하지 않습니다.
2. 조회 기간내에 보정이 일어나는 날짜의 전날 부터 수치에 비율을 곱한 값이 보정된 결과입니다.
즉, 날짜의 역순으로 보정이 이루어 집니다.
3. 조회 기간내에 보정해야 하는 비율이 여러개이면 마찬가지로 최근비율부터 보정후 차례대로 보정된 값에서 다시 보정이 됩니다.
4. 조회 기간내에 보정해야 하는 비율이 없다면 보정하지 않고 원래의 값을 보여 줍니다.
날짜 | 수치 | 보정수치 | |
2020-05-07 | 7 | 8.4 | |
기간내에 보정이 한 건 해당 | 2020-05-08 | 8 | 9.6 |
조회 기간 | 2020-05-09 | 9 | 9 |
2020-05-7~2020-05-12 | 2020-05-10 | 10 | 10 |
2020-05-11 | 11 | 1 | |
2020-05-12 | 12 | 12 |
날짜 | 수치 | 보정수치 | |
2020-05-07 | 7 | 16.8 | |
2020-05-08 | 8 | 19.2 | |
2020-05-09 | 9 | 18 | |
2020-05-10 | 10 | 20 | |
기간내에 보정이 두 건 해당 | 2020-05-11 | 11 | 22 |
조회 기간 | 2020-05-12 | 12 | 24 |
2020-05-07~2020-05-19 | 2020-05-13 | 13 | 26 |
2020-05-14 | 14 | 28 | |
2020-05-15 | 15 | 30 | |
2020-05-16 | 16 | 32 | |
2020-05-17 | 17 | 34 | |
2020-05-18 | 18 | 36 | |
2020-05-19 | 19 | 19 |
기간내에 보정이 없음 | 날짜 | 수치 | 보정수치 |
조회 기간 | 2020-05-01 | 1 | 1 |
2020-05-01~2020-05-08 | 2020-05-02 | 2 | 2 |
2020-05-03 | 3 | 3 | |
2020-05-04 | 4 | 4 | |
2020-05-05 | 5 | 5 | |
2020-05-06 | 6 | 6 | |
2020-05-07 | 7 | 7 | |
2020-05-08 | 8 | 8 |
이러한 자료처리를 하려면 어떤 SQL구문을 써야하는지 모르겠네요 고수님들 부탁드립니다.
WITH dtTbl (dt, vals ) AS ( SELECT TO_CHAR( TO_DATE('202005', 'YYYYMM') + (LEVEL-1) , 'YYYY-MM-DD'), LEVEL FROM DUAL CONNECT BY LEVEL <= 21 ), rtTbl (dt, rto ) AS ( SELECT '2020-05-09', 120 FROM dual UNION ALL SELECT '2020-05-19', 200 FROM dual ) SELECT TBL.ddt rtDate , TBL.dvals rtValue , dvals * ( CASE WHEN ddt = rdt THEN NVL(LEAD(rt) OVER(ORDER BY ddt) , 1) ELSE rt END ) AS colc_Value FROM ( SELECT dtTbl.dt as ddt , dtTbl.vals dvals, rtTbl.dt rdt , ROUND(EXP(SUM(LN( CASE WHEN rtTbl.rto IS NULL THEN 1 ELSE rtTbl.rto/100 END )) OVER (ORDER BY dtTbl.dt DESC)),2) rt FROM dtTbl LEFT JOIN rtTbl ON dtTbl.dt = rtTbl.dt -- WHERE dttbl.dt BETWEEN '2020-05-07' AND '2020-05-12' -- 보정 1건 WHERE dttbl.dt BETWEEN '2020-05-07' AND '2020-05-19' -- 보정 2건 -- WHERE dtTbl.dt BETWEEN '2020-05-01' AND '2020-05-08' -- 보정 없음 ) TBL ORDER BY rtDate
WITH base_t AS ( SELECT '2020-05-01' dt, 1 v FROM dual UNION ALL SELECT '2020-05-02', 2 FROM dual UNION ALL SELECT '2020-05-03', 3 FROM dual UNION ALL SELECT '2020-05-04', 4 FROM dual UNION ALL SELECT '2020-05-05', 5 FROM dual UNION ALL SELECT '2020-05-06', 6 FROM dual UNION ALL SELECT '2020-05-07', 7 FROM dual UNION ALL SELECT '2020-05-08', 8 FROM dual UNION ALL SELECT '2020-05-09', 9 FROM dual UNION ALL SELECT '2020-05-10', 10 FROM dual UNION ALL SELECT '2020-05-11', 11 FROM dual UNION ALL SELECT '2020-05-12', 12 FROM dual UNION ALL SELECT '2020-05-13', 13 FROM dual UNION ALL SELECT '2020-05-14', 14 FROM dual UNION ALL SELECT '2020-05-15', 15 FROM dual UNION ALL SELECT '2020-05-16', 16 FROM dual UNION ALL SELECT '2020-05-17', 17 FROM dual UNION ALL SELECT '2020-05-18', 18 FROM dual UNION ALL SELECT '2020-05-19', 19 FROM dual UNION ALL SELECT '2020-05-20', 20 FROM dual UNION ALL SELECT '2020-05-21', 21 FROM dual ) , rat_t AS ( SELECT '2020-05-09' dt, 120 r FROM dual UNION ALL SELECT '2020-05-19', 200 FROM dual ) SELECT a.dt , a.v , b.r , a.v * NVL(ROUND(EXP( SUM(LN(b.r/100)) OVER(ORDER BY a.dt ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) ), 3), 1) x FROM base_t a , rat_t b WHERE a.dt = b.dt(+) AND a.dt BETWEEN '2020-05-07' AND '2020-05-19' ;