[수정본] 내역 관리 질문입니다^^ 0 5 2,648

by 호야 [SQL Query] [2009.12.07 11:19:18]


서브 쿼리 업데이트 관련 질문입니다.

 

RS_NO

IN_PAY

OUT_PAY

UP_DATE

USR_NO

STATE

1234

1000

-100

30105

1234

0

1235

2000

0

30105

1234

0

1236

500

0

30105

1234

0

1237

700

-200

30106

1234

0

1238

100

0

30105

1234

0

1239

600

0

30105

1234

0

1240

100

0

30105

1234

0

WITH QQ AS
(SELECT 1234 RS_NO, 1000 IN_PAY, -100 OUT_PAY,’030105’ UP_DATE ,1234 USR_NO,0 STATE FROM DUAL UNION ALL
SELECT 1235 RS_NO, 2000 IN_PAY, 0 OUT_PAY,’030105’ UP_DATE ,1234 USR_NO,0 STATE FROM DUAL UNION ALL
SELECT 1236 RS_NO, 500 IN_PAY, 0 OUT_PAY,’030105’ UP_DATE ,1234 USR_NO,0 STATE FROM DUAL UNION ALL
SELECT 1237 RS_NO, 700 IN_PAY, -200 OUT_PAY,’030106’ UP_DATE ,1234 USR_NO,0 STATE FROM DUAL UNION ALL
SELECT 1238 RS_NO, 100 IN_PAY, 0 OUT_PAY,’030105’ UP_DATE ,1234 USR_NO,0 STATE FROM DUAL UNION ALL
SELECT 1239 RS_NO, 600 IN_PAY, 0 OUT_PAY,’030105’ UP_DATE ,1234 USR_NO,0 STATE FROM DUAL UNION ALL
SELECT 1240 RS_NO, 100 IN_PAY, 0 OUT_PAY,’030105’ UP_DATE ,1234 USR_NO,0 STATE FROM DUAL)
SELECT * FROM QQ

여기에서 -4500원이라는 입력을 넣었을 때... 아래와 같은 결과를 얻고 싶습니다.

RS_NO

IN_PAY

OUT_PAY

UP_DATE

USR_NO

STATE

1234

1000

-1000

현재날짜

1234

1

1235

2000

-2000

현재날짜

1234

1

1236

500

-500

현재날짜

1234

1

1237

700

-700

현재날짜

1234

1

1238

100

-100

현재날짜

1234

1

1239

600

-500

현재날짜

1234

0

1240

100

0

30105

1234

0

 

이렇게 만들어진 결과물로 QQ라는 테이블을 업데이트를 시키고 싶습니다.

MODEL 절로 어떻게 해 볼까 하고.. 고민하다가 그만.ㅠ..ㅠ 능력이 부족해 쿼리로 해 버렸습니다.

조금더 낳은 방안이 있으시다면 조언 부탁드립니다.

쿼리만 풀었을 경우

 

SELECT RS_OUT_PAY,RS_UPDATE,DECODE(USR_RS_IN_PAY+RS_OUT_PAY,0,1,0) RS_STATE
FROM (SELECT USR_RS_NO,CASE WHEN SR<=0 THEN USR_RS_IN_PAY*-1 ELSE LEAST((USR_RS_IN_PAY-SR)*-1,0) END RS_OUT_PAY, TOD_STAMP(SYSDATE) RS_UPDATE,USR_RS_IN_PAY
FROM (SELECT USR_RS_NO,USR_RS_IN_PAY,USR_RS_OUT_PAY,SUM(USR_RS_IN_PAY+USR_RS_OUT_PAY) OVER(ORDER BY USR_RS_NO) + -4500 SR
FROM QQ
WHERE USR_NO=1234 AND USR_RS_STATE=0)
WHERE USR_RS_OUT_PAY<>CASE WHEN SR<=0 THEN USR_RS_IN_PAY*-1 ELSE LEAST((USR_RS_IN_PAY-SR)*-1,0) END
)

 

상위 쿼리를  UPDATE 에 적용 할려니.. WHERE 절에도

한번더 계산을 없앤 서브쿼리를 더 날려야 되네요... 좋은 방안이 없을 까요?

제가 UPDATE를 하는 방법입니다. 돌아가긴 하지만 문제는 부하가 걱정입니다.

UPDATE QQ A
        SET (A.USR_RS_OUT_PAY,A.USR_RS_UPDATE,A.USR_RS_STATE)=(SELECT RS_OUT_PAY,RS_UPDATE,DECODE(USR_RS_IN_PAY+RS_OUT_PAY,0,1,0) RS_STATE
                                                                  FROM (SELECT USR_RS_NO,CASE WHEN SR<=0 THEN USR_RS_IN_PAY*-1 ELSE LEAST((USR_RS_IN_PAY-SR)*-1,0) END RS_OUT_PAY, TOD_STAMP(SYSDATE) RS_UPDATE,USR_RS_IN_PAY
                                                                  FROM (SELECT USR_RS_NO,USR_RS_IN_PAY,USR_RS_OUT_PAY,SUM(USR_RS_IN_PAY+USR_RS_OUT_PAY) OVER(ORDER BY USR_RS_NO) + -4500SR
                                                                  FROM USER_CASH_RESERVE_H B
                                                                  WHERE USR_NO=1234 AND USR_RS_STATE=0)
                                                                  WHERE USR_RS_OUT_PAY<>CASE WHEN SR<=0 THEN USR_RS_IN_PAY*-1 ELSE LEAST((USR_RS_IN_PAY-SR)*-1,0) END
                                                                  )WHERE A.USR_RS_NO=USR_RS_NO)
        WHERE USR_RS_NO IN (SELECT USR_RS_NO
                            FROM (SELECT USR_RS_NO,USR_RS_IN_PAY,USR_RS_OUT_PAY,SUM(USR_RS_IN_PAY+USR_RS_OUT_PAY) OVER(ORDER BY USR_RS_NO) + -4500 SR
                                 FROM USER_CASH_RESERVE_H B
                                  WHERE USR_NO=1234 AND USR_RS_STATE=0)
                            WHERE USR_RS_OUT_PAY<>CASE WHEN SR<=0 THEN USR_RS_IN_PAY*-1 ELSE LEAST((USR_RS_IN_PAY-SR)*-1,0) END);

by 호야 [2009.12.07 11:47:42]
오라클 버전은 11g R2 입니다..ㅠ..ㅠ

by 마농 [2009.12.07 13:13:15]
Merge 구문을 이용해서 Update해보세요.

by 호야 [2009.12.07 13:31:24]
MODEL 절로 위의 쿼리를 구할수는 없나요?

by 마농 [2009.12.07 14:28:25]
모델절로 안될것은 없지만.. 모델절이 모든것을 다 해결해 주는 것은 아닙니다.
그때 그때 살황에 맞는 최선의 방법을 구하셔야죠.
방법부터 정해 놓고 결과를 도출하려다 보면 한계에 부딪히게 됩니다.
쿼리를 만들어 냈다 하더라도 억지스런 모양새가 되어버리고요.

WITH qq AS
(
SELECT 1234 usr_rs_no, 1000 usr_rs_in_pay, -100 usr_rs_out_pay, '030105' usr_rs_update, 1234 usr_no, 0 usr_rs_state FROM dual
UNION ALL SELECT 1235, 2000, 0, '030105', 1234, 0 FROM dual
UNION ALL SELECT 1236, 500, 0, '030105', 1234, 0 FROM dual
UNION ALL SELECT 1237, 700, -200, '030106', 1234, 0 FROM dual
UNION ALL SELECT 1238, 100, 0, '030105', 1234, 0 FROM dual
UNION ALL SELECT 1239, 600, 0, '030105', 1234, 0 FROM dual
UNION ALL SELECT 1240, 100, 0, '030105', 1234, 0 FROM dual
)
SELECT *
FROM qq
WHERE usr_no = 1234
AND usr_rs_state = 0
MODEL
PARTITION BY (usr_no)
DIMENSION BY (usr_rs_no)
MEASURES (usr_rs_in_pay, usr_rs_out_pay, usr_rs_state, 0 sr)
IGNORE NAV
RULES
(sr[ANY] = sr[CV()-1] + usr_rs_in_pay[CV()] + usr_rs_out_pay[CV()]
, usr_rs_out_pay[ANY] = CASE WHEN sr[CV()] <= 4500 THEN -usr_rs_in_pay[CV()]
WHEN sr[CV()] - (usr_rs_in_pay[CV()] + usr_rs_out_pay[CV()]) > 4500 THEN 0
ELSE sr[CV()] - (usr_rs_in_pay[CV()] + usr_rs_out_pay[CV()]) - 4500 END
, usr_rs_state[ANY] = CASE WHEN usr_rs_in_pay[CV()] = -usr_rs_out_pay[CV()] THEN 1 ELSE 0 END
)
;

by 호야 [2009.12.07 19:18:42]
그렇네요... 정말 감사합니다..^^;
역시 쿼리는 마농님에게 배워야 되는거 같습니다
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입