2009-07-28 5 views
3

아래 열거 된 두 개의 열이있는 두 개의 테이블을 다루고 있습니다.단일 열의 모든 행을 업데이트하십시오.

표 1 : table_snapshot account_no | balance_due

표 2 : 테이블 지급 됨 account_no | post_balance |

ALTER TABLE table_paid ADD delta_balance number(18); 

내가 1 사이의 균형의 차이와 함께 새 열 (delta_balance)를 업데이트하려면 다음 쿼리를 사용하려고 해요 :

delta_balance 나는 다음과 같은 명령을 사용하여 표 2에 세 번째 열을 추가 2. 참고로 table_paid는 table_snapshot의 하위 집합입니다. i, 즉 테이블 2는 테이블 1에있는 계정이 몇 개 밖에 없습니다. SQL 문이 제대로 종료되지 않았습니다. 내가 사용하는 쿼리는 다음과 같습니다.

UPDATE table_paid 
SET table_paid.delta_balance = table_paid.post_balance - table_snapshot.balance_due 
from table_paid, table_snapshot 
WHERE table_paid.account_no = table_snapshot.account_no; 

누군가 내 쿼리를 수정할 수 있으면 감사합니다.

감사합니다.

초심자.

답변

4

오라클이없는 (table_paid.account_no = table_snapshot.account_no WHERE table_snapshot 에서 balance_due를 선택) 업데이트 ... MS SQL Server에서 사용하는 구문에서 (필자는 ANSI가 아닙니다.)

UPDATE (SELECT tp.delta_balance 
       , tp.post_balance 
       , ts.balance_due 
      FROM table_paid tp 
        JOIN table_snapshot ts 
        ON tp.account_no = ts.account_no 
     ) 
    SET delta_balance = post_balance - balance_due; 

이 더 "정확한"입니다 : 당신이 결과 집합에 업데이 트를해야 할 때 대신, 오라클은 다음과 같이 뷰를 통해 업데이트, 인라인 뷰의 일종으로 결과 집합을 만들 수있다 table_snapshot에 해당 행이 없더라도 쿼리가 table_paid의 모든 행을 업데이트하므로 Babar 및 palindrom이 제공하는 응답보다 빠릅니다. 1-1 대응이 있다면 걱정할 필요는 없지만 인라인보기를 사용하면 더 안전합니다.

부모 테이블인지 또는 상위 테이블인지 account_no가 다른 테이블의 기본 키 (아마도 계정 또는 "table_account")를 가리키고 있는지 분명하지 않습니다. 명명 규칙). 어떤 경우에도 테이블에 1-1 서신이 없다는 것이 분명합니다. 하나는 15K, 다른 하나는 수백만입니다.

이것은 두 가지를 의미 할 수 있습니다. table_paid에 해당 행이 없거나 table_paid의 각 행에 대해 table_snapshot에 많은 행이있는 table_snapshot의 행이 많습니다. 후자가 사실이라면 쿼리를 수행 할 수 없습니다. table_paid의 각 행에 대해 여러 업데이트를 수행하므로 결과를 예측할 수 없습니다. "post_balance - balance_due"표현 중 어느 것이 주어진 delta_balance의 값을 궁극적으로 결정할 것인가를 어떻게 알 수 있습니까?

내 쿼리를 실행하면 충분히 빨리 알 수 있습니다. "ORA-01779 : 키가 아닌 테이블에 매핑되는 열을 수정할 수 없습니다"라는 오류 메시지가 나타납니다. 이 오류는 테이블의 데이터가 아닌 (두 테이블에 정의 된 기본 키를 기반으로 할 수도 있음) 기반으로 나타납니다.지정한 조인 조건이 정의 된 키를 기반으로 업데이트 된 테이블과 나머지 조인간에 명확한 1-1 관계를 나타내지 않으면이 오류가 발생합니다. 오라클은 "데이터를 망칠 것"이라고 말합니다.

실제로 다른 문제가 발생할 데이터가있는 경우 다른 답변에서 오류 (이 경우 ORA-01427 : 단일 행 하위 쿼리는 둘 이상의 행을 반환 함) 만 표시됩니다. 내 버전이 더 엄격하므로 다른 버전을 사용해야 할 수도 있습니다.

다른 사람들이 말했듯이 table_snapshot 테이블의 account_no에 대한 색인을 원할 것입니다. table_paid에서 하나는 아프지 않을 것입니다.

+0

우수 .. 자세한 정보 주셔서 감사합니다! – novice

4

UPDATE table_paid 
SET table_paid.delta_balance = table_paid.post_balance - 
(SELECT table_snapshot.balance_due from table_snapshot WHERE table_paid.account_no = 
table_snapshot.account_no); 
1

UPDATE는 SET의 table_paid.delta_balance = table_paid.post_balance을 table_paid보십시오 -

+0

안녕하세요 babar 및 palindrom, 쿼리가 전체 테이블 스캔으로 진행 중이며 아직 실행 중입니다. 표 1에는 약 130 만 개의 레코드가 있고 표 2에는 15k 개의 레코드가 있습니다. 스캔 속도를 높이는 방법에 대한 제안 사항이 있으십니까? 안부! – novice

+0

자세한 내용은 Tom Kyte가 여러 행의 업데이트에 대해 무엇을 말해야하는지 확인하십시오. http://asktom.oracle.com/pls/asktom/f?p=100:11:0::NO::P11_QUESTION_ID:6407993912330 – jva

+1

create 당신이 이미 가지고 있지 않다면 table1 (account_no)에 대한 색인. – palindrom

관련 문제