2014-01-25 7 views
0

여러 시스템에서 수집 한 데이터가있는 매우 큰 테이블이 있습니다. 이제 조건과 여러 열을 기반으로 중복 레코드를 삭제해야합니다. 만족 다음 조건으로 중복 제거, 상기 데이터로부터Oracle 다중 데이터베이스 열과 조건을 기반으로 중복 제거 방법을 사용하십시오.

+---------------+-------------+------+-----+-------- 
| System ID  | Debt Num | Exp Dt | Account NO | 
+---------------+-------------+------+-----+--------- 
| pay   | 2222  | 0114 | 111  | 
| pay   | 2222  | 0214 | 111  | 
| Online  | 2222  | 0214 | 111  | 
| Online  | 3333  | 0115 | 222  | 
| Online  | 3333  | 0116 | 222  | 
| ERP   | 2222  | 0214 | 111  | 
| ERP   | 4444  | 0114 | 333  | 
+---------------+-------------+------+-----+-------- 

: 여기

는 일례이다.

  • 중복 행 그룹을 차변 번호, exp dt, 계좌 번호로 삭제하고 max (exp dt)로 한 레코드를 유지하십시오.
  • 보관할 레코드의 우선 순위는 System ID입니다. 1) 지불 2) 온라인 및 3) ERP. 위의 계정 111에 대해 우리는 세 시스템의 기록을 가지고 있으며, 직불 카드의 최대 (exp dt)는 세 시스템의 0214입니다. exp dt = 0214 인 Pay의 레코드 만 유지해야하며 나머지는 삭제해야합니다.
  • 위의 예와 마찬가지로 222 계정에 대해 지불 한 레코드가 없으므로 시스템 온라인과 ERP 중 우선 순위를 지정하여 최대 (exp dt)를 유지해야합니다.

그룹별로 row_number와 같은 온라인에서 여러 쿼리를 시도했지만 모두 하나의 조건 만 수행했습니다.

귀하의 의견과 제안에 도움을 주시면 감사하겠습니다.

EDIT : Gordon의 쿼리는 잘 작동하고 내 요구 사항에 맞지만 540K 행을 포함하는 준비 작업을 실행하면 ORA-00600 내부 오류가 발생합니다.

+0

Oracle MERGE 명령을 살펴 보셨습니까? – scraatz

+0

@scraatz 지금까지는. 필자는 http://www.oracle-base.com/articles/10g/merge-enhancements-10g.php에서 일치하지 않는 예제를'머지 (merge) '로 보았습니다. 이 올바른지? 더 나은 참조가 있습니까? 좋은 생각과 좋은 제안. 나는 밖으로 시험 할 것이다. – dicaprio

+0

죄송합니다. 비슷한 문제를 해결하려고 할 때만 최근에 발견되었습니다. Oracle에서 가능하지 않은 조인 된 테이블에서 삭제할 수있는 다른 데이터베이스와 마찬가지로 "조인에서 oracle 삭제"에 대해 봤습니다. – scraatz

답변

1

난 당신이 rowid과 상관 하위 쿼리와 함께이 작업을 수행 할 수 있다고 생각 :

delete from payinfo_staging_db 
    where rowid <> (select rowid 
        from (select rowid 
         from payinfo_staging_db t2 
         where t2.debitNum = payinfo_staging_db.debitNum and 
           t2.accountNo = payinfo_staging_db.accountNo 
         order by t2.exp_dt, 
            (case when t2.SystemId = 'Pay' then 1 
             when t2.SystemId = 'Online' then 2 
             when t2.SystemId = 'ERP' then 3 
            end) 
         ) r 
        where rownum = 1 
       ); 

편집 :

오라클에 중첩 된 참조에 문제가있을 수 있어야합니다. (제대로 분석하고 실행하는 의미에서 적어도) 다음 작품 :

delete from payinfo_staging_db 
    where rowid <> (select min(rowid) keep (dense_rank first order by exp_dt desc, 
                  (case when t2.SystemId = 'Pay' then 1 
                    when t2.SystemId = 'Online' then 2 
                    when t2.SystemId = 'ERP' then 3 
                  end) 
             ) as therowid 
        from payinfo_staging_db t2 
        where t2.debitNum = payinfo_staging_db.debitNum and 
         t2.accountNo = payinfo_staging_db.accountNo 
       ); 

는 SQL 바이올린은 here입니다.

+0

나는 위의 시도와 오류를 통지 t.debitNum : 잘못된 식별되었습니다. 하위 쿼리에서 테이블 별칭't'가 유효합니까? – dicaprio

+0

테이블의 이름은 무엇입니까? –

+0

내 테이블 이름이 payinfo_staging_db인데, 나는'from t'를'payinfo_staging_db t'와'from t t2'를'from payinfo_staging_db t2'로 대체했습니다. 희망이 맞습니다. – dicaprio

관련 문제