2012-11-09 70 views
0

我有下面的代碼來檢測單個表中重複:需要幫助理解Oracle分析功能

 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 
     ); 

我GOOGLE了這麼多的網站,發現大多數人遵循這一有效方式。但是沒有我在哪裏找到了關於這些嵌套查詢如何工作的正確解釋。

回答

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.                             

UPDATE:

我所試圖做的是我發現,在表中的一個條目,重複在同一個表 ,所有這些元素將與DUPL標誌來標示, 包括原始項

仍然不需要分析。只需在您的子查詢中添加having count(*) = 1,以便您只更新非唯一行。 Having子句基本上是集合函數的where條件,而不需要將查詢包裝在子查詢中。它最後執行。

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這個例子和你的完全一樣。它更新重複行重複字符 –