2016-07-10 2 views
0

수량 및 나머지 열이있는 테이블이 있으며 일부 날짜 열에 주문한 후 테이블의 모든 행을 업데이트해야합니다.오라클 - 이전 행 값을 기준으로 순차적 행을 업데이트하는 가장 빠른 방법

나머지 열의 값은 (이전 행의 나머지) + 또는 - (이 행의 수량)에 의해 계산됩니다. 이 작업을 수행하기 위해 커서 루프를 작성했지만 완료하려면 시간이 오래 걸립니다.

OPEN KAL; 
     LOOP 
     FETCH KAL 
      INTO V_PK_ID, V_TYPE_ID, V_QUANTITY; 

     IF (V_TYPE_ID = 1) THEN 
      V_REMAINING := V_REMAINING + V_QUANTITY; 
     ELSE 
      V_REMAINING := V_REMAINING - V_QUANTITY; 
     END IF; 

     UPDATE TABLE K 
      SET K.REMAINING = V_REMAINING 
     WHERE K.KALAMAZOO_ID = V_PK_ID; 

     END LOOP; 
CLOSE KAL; 

이 작업을 빨리 수행 할 수있는 방법이 있습니까? 아니면이를 수행하는 데 사용할 수있는 다른 방법이 있습니까?

편집 : "1000"로 시작하는 경우, 데이터 예를 들어

PK TYPE QUANTITY REMAINING 
1 1  100   900 
2 2  50   950 
3 2  25   975 
4 1  200   775 
5 1  125   650 
6 1  50   600 

을 샘플 1을위한 (-) 및 타입 2의 (+), 행은 상기와 같이 업데이트 될 예정입니다 .

+2

예제 테이블 데이터 및 쿼리를 표시하십시오 – OldProgrammer

+0

테이블에 표시된 1000은 어디에 있습니까? 아니면 다른 방법으로 입력합니까? – mathguy

+0

또한 기본 테이블 구조입니까, 아니면보기를 위해이 작업을 수행하고 있습니까? 기본 테이블 인 경우 'remaining'은 가상 열 (https://oracle-base.com/articles/11g/virtual-columns-11gr1)이어야합니다. 저장된 열로 저장하면 기본 정규화 원칙을 위반하게됩니다. – mathguy

답변

3

merge으로이를 수행 할 수 있습니다. 논리는 다음과 같습니다.

merge into k 
     using (select k.*, 
        sum(case when v_type_id = 1 then v_quantity else - v_quantity end) over 
         (order by v_pk_id) as new_remaining 
      from k 
      ) s 
     on (k.v_pk_id = s.v_pk_id) 
when matched then 
    update set k.remaining = s.new_remaining; 

계산시 PL/SQL 루프가 필요하지 않습니다.

+0

@ 모토로라. . . 이 대답에 대한 편집을 거부하지 않았습니다. –

+0

@ 모토로라. . . 고맙습니다. –