2012-11-09 8 views
0

나는 하나의 테이블에서 중복을 감지 할 수있는 다음과 같은 코드가 있습니다이해 오라클 분석 함수에 도움이 필요

 UPDATE tab 
     SET dup = 'Y' 
     WHERE ROWID IN 
     (SELECT tab_o.ROWID 
      FROM tab tab_o, 
      (SELECT * 
      FROM tab tab_i 
      WHERE ROWID IN 
       (SELECT ROWID 
       FROM 
       (SELECT ROWID, 
        ROW_NUMBER() OVER(PARTITION BY a, b, c ORDER BY a, b, c) dupl 
       FROM tab 
       WHERE a IS NOT NULL 
        AND a = 1 
        AND b = 1 
        AND c = 3 
       ) 
       WHERE dupl > 1 
      ) 
     ) res 
     WHERE tab_o.a = res.a 
      AND tab_o.b = res.b 
      AND tab_o.c = res.c 
     ); 

내가 너무 많은 웹 사이트를 검색 좀하고, 대부분의 사람들이 효율적인 방법을 따르는 것이 발견합니다. 그러나 어디에서 이러한 중첩 쿼리가 작동하는지에 대한 적절한 설명을 찾지 못했습니다.

답변

1

간단하게하십시오. 분석이 필요 없습니다.

샘플 테이블 :이

12:57:37 [email protected]> create table dupe_test 
        2 (a number, b number, c number, is_dupe char); 

Table created.                   

12:57:50 [email protected]> insert all      
12:57:50 2 into dupe_test values (1, 1, 1, 'n') 
12:57:50 3 into dupe_test values (1, 1, 1, 'n') 
12:57:50 4 into dupe_test values (1, 1, 1, 'n') 
12:57:50 5 into dupe_test values (1, 2, 1, 'n') 
12:57:50 6 into dupe_test values (1, 2, 1, 'n') 
12:57:50 7 into dupe_test values (1, 2, 1, 'n') 
12:57:50 8 select * from dual;     

6 rows created.          

그것입니다

12:58:17 [email protected]> select * from dupe_test; 

     A   B   C I    
---------- ---------- ---------- -    
     1   1   1 n    
     1   1   1 n    
     1   1   1 n    
     1   2   1 n    
     1   2   1 n    
     1   2   1 n    

6 rows selected.        

고유 값 :

12:59:35 [email protected]> select rowid, t.* 
        2 from dupe_test t 
        3 where rowid in (select min(rowid) 
        4     from dupe_test 
        5     group by a, b, c); 

ROWID      A   B   C I                   
------------------ ---------- ---------- ---------- -                   
AAARN1AABAAAO9JAAD   1   2   1 n                   
AAARN1AABAAAO9JAAA   1   1   1 n                   

업데이트 및 결과 :

12:59:51 [email protected]> update dupe_test t 
        2 set is_dupe = 'y' 
        3 where rowid not in (select min(rowid) 
        4      from dupe_test 
        5      group by a, b, c); 

4 rows updated.                              

13:00:45 [email protected]> select * from dupe_test;                      

     A   B   C I                         
---------- ---------- ---------- -                         
     1   1   1 n                         
     1   1   1 y                         
     1   1   1 y                         
     1   2   1 n                         
     1   2   1 y                         
     1   2   1 y                         

6 rows selected.                             

업데이트 : 내가 뭘하려고 오전 나는 이러한 모든 항목이 원래 항목

포함 DUPL 플래그 표시 됩니다 테이블에 하나 개의 항목이 같은 테이블에 반복되는 것을 발견

아직 분석이 필요하지 않습니다. 하위 쿼리에 having count(*) = 1을 추가하면 고유하지 않은 행만 업데이트됩니다. Having 절은 기본적으로 하위 쿼리에서 쿼리를 래핑 할 필요없이 집계 함수의 where-condition입니다. 마지막으로 실행됩니다.

11:03:00 [email protected]> insert into dupe_test values (1,3,1,'n') -- add some unique row 
11:03:09 2/                  

1 row created.                  

11:03:10 [email protected]> update dupe_test set is_dupe = 'y'        
11:03:27 2 where rowid not in              
11:03:34 3 (select min(rowid) from dupe_test          
11:03:51 4 group by a,b,c               
11:04:00 5 having count(*) = 1);             

6 rows updated.                  

11:04:06 [email protected]> select * from dupe_test;          

     A   B   C I             
---------- ---------- ---------- -             
     1   1   1 y             
     1   1   1 y             
     1   1   1 y             
     1   2   1 y             
     1   2   1 y             
     1   2   1 y             
     1   3   1 n             

7 rows selected.                  
+0

이 새로운 발명품 인 캐리지 리턴이 자동으로 코드를 읽기 쉽게 만듭니다. 당신은 언젠가 그것을 밖으로 시도해야합니다! ;) – APC

+0

멋지고 쉬운 예제 APC를 보내 주셔서 감사합니다. 하지만 제 경우에는 모든 중복 행을 중복 된 문자로 업데이트해야합니다. – user613114

+0

@ user613114이 예제는 귀하의 것과 똑같습니다. 중복 된 문자로 중복 된 행을 업데이트합니다. –