** 데이터를 비율 컬럼의 합계를 1로 업데이트를 하는 걸 만들고 있습니다.
테이블 명은 Test , 컬럼 a,b,c,d ,날짜, 키값, 비율 , 등록일, 수정일 , 등록자, 수정자 로 구성되어 있습니다.
날짜와 키값을 기준으로 ab,c,d 컬럼의 order by 순서 대로 프로시져로 비율의 값을 0.0001 이나 0.0001 로 빼줘서 비율의 합이 1이 되도록 하려고 합니다.
-- 대상이 되는 키값, 현재까지 비율의 합 , 처리해야할 갯수를 조회하고 , +인지 - 인지 확인 하고 loop 실행
FOR c0 IN (
SELECT 키값
, SUM(비율) SUM_PRC_RATIO /* 비율의 합 */
, ABS((1.0 - SUM(비율)) / 0.0001) AS GAP_LIMIT /* 처리해야할 갯수 */
, CASE WHEN (1.0 - SUM(비율)) > 0.0 THEN '+'
ELSE '-'
END AS GAP_OPER
FROM test
날짜= '201806' and 키값 = '키'
GROUP BY 키값
HAVING SUM(PRC_RATIO) != 1
) LOOP
loop
for c1 in (selelct a,b,c,d ,날짜, 키값, 비율 from Test where 날짜= '201806' and 키값 = '키' --조회 ) loop
update test set 비율 = 비율 + (0.0001) ;--(0.0001)
selelct sum(비율) into sums from Test where 날짜= '201806' and 키값 = '키' ;--조회
exit when sums :=1 ;
end loop ;
end loop ;
===================================================
샘플 예제
===================================================
-- 1. 업데이트 대상 확인 --WITH test AS(SELECT 1 id, '201806' dt, 1 a, 1 b, 1 c, 1 d, 0.5000 prc_ratio FROM dualUNION ALL SELECT 1, '201806', 1, 1, 1, 2, 0.4990 FROM dualUNION ALL SELECT 1, '201806', 1, 1, 1, 3, 0.0002 FROM dualUNION ALL SELECT 1, '201806', 1, 1, 1, 4, 0.0002 FROM dualUNION ALL SELECT 1, '201806', 1, 1, 1, 5, 0.0002 FROM dualUNION ALL SELECT 2, '201806', 1, 1, 1, 1, 0.5000 FROM dualUNION ALL SELECT 2, '201806', 1, 1, 1, 2, 0.4990 FROM dualUNION ALL SELECT 2, '201806', 1, 1, 1, 3, 0.0001 FROM dualUNION ALL SELECT 2, '201806', 1, 1, 1, 4, 0.0001 FROM dualUNION ALL SELECT 2, '201806', 1, 1, 1, 5, 0.0001 FROM dualUNION ALL SELECT 3, '201806', 1, 1, 1, 1, 0.5000 FROM dualUNION ALL SELECT 3, '201806', 1, 1, 1, 2, 0.4990 FROM dualUNION ALL SELECT 3, '201806', 1, 1, 1, 3, 0.0004 FROM dualUNION ALL SELECT 3, '201806', 1, 1, 1, 4, 0.0004 FROM dualUNION ALL SELECT 3, '201806', 1, 1, 1, 5, 0.0004 FROM dual)SELECT id, dt , a, b, c, d , prc_ratio , rn , (FLOOR(cnt2 / cnt1) + CASE WHEN rn <= MOD(cnt2, cnt1) THEN 1 ELSE 0 END) * s x FROM (SELECT id, dt , a, b, c, d , prc_ratio , ROW_NUMBER() OVER(PARTITION BY id, dt ORDER BY a, b, c, d) rn , COUNT(*) OVER(PARTITION BY id, dt) cnt1 , ABS (1 - SUM(prc_ratio) OVER(PARTITION BY id, dt)) / 0.0001 cnt2 , SIGN(1 - SUM(prc_ratio) OVER(PARTITION BY id, dt)) * 0.0001 s FROM test-- WHERE id = 1-- AND dt = '201806' );-- 2. Update --MERGE INTO test aUSING(SELECT rid , (FLOOR(cnt2 / cnt1) + CASE WHEN rn <= MOD(cnt2, cnt1) THEN 1 ELSE 0 END) * s x FROM (SELECT ROWID rid , ROW_NUMBER() OVER(PARTITION BY id, dt ORDER BY a, b, c, d) rn , COUNT(*) OVER(PARTITION BY id, dt) cnt1 , ABS (1 - SUM(prc_ratio) OVER(PARTITION BY id, dt)) / 0.0001 cnt2 , SIGN(1 - SUM(prc_ratio) OVER(PARTITION BY id, dt)) * 0.0001 s FROM test-- WHERE id = 1-- AND dt = '201806' ) WHERE (FLOOR(cnt2 / cnt1) + CASE WHEN rn <= MOD(cnt2, cnt1) THEN 1 ELSE 0 END) > 0) bON (a.ROWID = b.rid)WHEN MATCHED THENUPDATE SET a.prc_ratio = a.prc_ratio + b.x;출처 : http://www.gurubee.net/article/79760
by 마농 [2018.07.04 10:26:26]
'프로그램 > ORACLE' 카테고리의 다른 글
| 오라클 컬럼 숫자 세는 쿼리문 (1) | 2022.10.30 |
|---|---|
| 오라클 timestamp insert (0) | 2019.04.09 |
| 오라클 월별 주차 쿼리 (0) | 2017.10.25 |
| 오라클 컬럼명으로 테이블 찾는 쿼리문 (0) | 2015.06.06 |
| 오라클 날짜 차이 구하기 (0) | 2014.10.28 |