오라클 데이터 처리관련 질문 1 5 554

by 주작전사 [Oracle 기초] [2021.06.01 14:31:53]


기본 테이블
날짜 수치
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구문을 써야하는지 모르겠네요 고수님들 부탁드립니다.

 

by 뉴비디비 [2021.06.01 21:25:52]
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

 


by 주작전사 [2021.06.02 14:19:23]

감사합니다!!!


by 마농 [2021.06.02 08:40:27]
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'
;

 


by 주작전사 [2021.06.02 14:19:26]

감사합니다!!!


by 주작전사 [2021.06.02 14:16:13]

와우 이게 되는군요!! 두 분다 핵심적으로 쓰는 구문은 같네요. 고수분들은 역시 다르군요. 눈빠지게 들여다보고 공부하겠습니다.

감사합니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입