** 데이터를 비율 컬럼의 합계를 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
dual
UNION
ALL
SELECT
1,
'201806'
, 1, 1, 1, 2, 0.4990
FROM
dual
UNION
ALL
SELECT
1,
'201806'
, 1, 1, 1, 3, 0.0002
FROM
dual
UNION
ALL
SELECT
1,
'201806'
, 1, 1, 1, 4, 0.0002
FROM
dual
UNION
ALL
SELECT
1,
'201806'
, 1, 1, 1, 5, 0.0002
FROM
dual
UNION
ALL
SELECT
2,
'201806'
, 1, 1, 1, 1, 0.5000
FROM
dual
UNION
ALL
SELECT
2,
'201806'
, 1, 1, 1, 2, 0.4990
FROM
dual
UNION
ALL
SELECT
2,
'201806'
, 1, 1, 1, 3, 0.0001
FROM
dual
UNION
ALL
SELECT
2,
'201806'
, 1, 1, 1, 4, 0.0001
FROM
dual
UNION
ALL
SELECT
2,
'201806'
, 1, 1, 1, 5, 0.0001
FROM
dual
UNION
ALL
SELECT
3,
'201806'
, 1, 1, 1, 1, 0.5000
FROM
dual
UNION
ALL
SELECT
3,
'201806'
, 1, 1, 1, 2, 0.4990
FROM
dual
UNION
ALL
SELECT
3,
'201806'
, 1, 1, 1, 3, 0.0004
FROM
dual
UNION
ALL
SELECT
3,
'201806'
, 1, 1, 1, 4, 0.0004
FROM
dual
UNION
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 a
USING
(
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
) b
ON
(a.ROWID = b.rid)
WHEN
MATCHED
THEN
UPDATE
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 |