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

私は非常に多くのウェブサイトをグーグルで検索しましたが、ほとんどの人がこの効率的な方法に従っていることがわかりました. しかし、これらのネストされたクエリがどのように機能するかについての適切な説明を見つけた場所はありません。

4

1 に答える 1

1

もっと簡単にしてください。分析は必要ありません。

サンプルテーブル:

12:57:37 SYSTEM@dwal> create table dupe_test
                   2  (a number, b number, c number, is_dupe char);

Table created.                                                                           

12:57:50 SYSTEM@dwal> 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 SYSTEM@dwal> 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 SYSTEM@dwal> 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 SYSTEM@dwal> 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 SYSTEM@dwal> 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.                                                                                                                   

アップデート:

私がやろうとしているのは、テーブル内の 1 つのエントリが同じテーブルで繰り返されていることを発見したことです。そのようなエントリはすべて、元のエントリを含め、dupl フラグでマークされます。

まだ分​​析は必要ありません。サブクエリを追加having count(*) = 1するだけで、一意でない行のみを更新できます。Having句は基本的に、クエリをサブクエリでラップする必要のない集計関数の where 条件です。最後に実行されます。

11:03:00 SYSTEM@dwal> insert into dupe_test values (1,3,1,'n') -- add some unique row
11:03:09   2  /                                                                      

1 row created.                                                                       

11:03:10 SYSTEM@dwal> 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 SYSTEM@dwal> 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.                                                                     
于 2012-11-09T05:06:06.620 に答える