ORACLEクエリー重複レコード削除の3つの方法

4831 ワード

たとえば、名前、身分証明書番号、住所の3つのフィールドがまったく同じレコードをクエリーしたい人表(表名:peosons)があります.

   select p1.*   
  
from persons  p1,persons  p2  
where p1.id<>p2.id  
and  p1.cardid = p2.cardid and p1.pname = p2.pname and p1.address = p2.address

上記効果を奏することができる.
重複レコードを削除するいくつかのSQL文
1.rowidメソッドで
2.groupbyメソッドで
3.distinct法で
1.rowidメソッドで
Oracleバンドのrowidプロパティに基づいて、重複があるかどうかを判断します.文は次のとおりです.
データを調べる:

   select * from table1 a where rowid !=(select max(rowid) 
  
from table1 b where a.name1=b.name1 and a.name2=b.name2......)

データの削除:

   delete  from table1 a where rowid !=(select max(rowid) 
  
from table1 b where a.name1=b.name1 and a.name2=b.name2......)

2.groupbyメソッド
データを調べる:

   select count(num), max(name) from student --        ,     name   
  
group by num
having count(num) >1 -- num num ,

データの削除:

   delete from student 
  
group by num
having count(num) >1

これですべての重複を削除します.
3.distinctメソッドを使用-小さなテーブルに便利

   create table table_new as   select distinct *   from table1 minux 
  
truncate table table1;
insert into table1 select * from table_new;

重複記録の照会および削除方法の概要
1、テーブル内の余分な重複記録を検索し、重複記録は単一フィールド(peopleId)によって判断する

   select * from people 
  
where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1)

2、削除表の余分な重複記録、重複記録は単一フィールド(peopleId)で判断し、rowid最小の記録のみを残す

   delete from people 
  
where peopleId in (select peopleId from people group by peopleId  
having count(peopleId) > 1)
and rowid not in (select min(rowid) from people group by peopleId having count(peopleId )>1)

3、テーブル内の余分な重複レコードの検索(複数フィールド)

   select * from vitae a 
  
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)

4、テーブルの余分な重複記録(複数フィールド)を削除し、rowidの最小記録のみを残す

   delete from vitae a 
  
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)

5、rowid最小のレコードを含まないテーブル内の余分な重複レコード(複数のフィールド)を検索する

   select * from vitae a 
  
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)

(二)
たとえば、Aテーブルにフィールド「name」が存在し、異なるレコード間の「name」の値が同じになる可能性があります.これで、テーブル内の各レコード間に「name」の値が重複する項目があることをクエリーする必要があります.

   Select Name,Count(*) From A Group By Name Having Count(*) > 1 
 

また、性別も同じ大きさであることを調べると、以下のようになります.

   Select Name,sex,Count(*) From A Group By Name,sex Having Count(*) > 1 
 

(三)
方法1

   declare @max integer,@id integer 
  
declare cur_rows cursor local for select ,count(*) from group by having count(*) >; 1
open cur_rows
fetch cur_rows into @id,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
delete from where = @id
fetch cur_rows into @id,@max
end
close cur_rows
set rowcount 0

方法2
「重複レコード」には、完全に重複したレコード、つまりすべてのフィールドが重複したレコード、およびNameフィールドなどの一部のキーフィールドが重複したレコードの2つの意味がありますが、他のフィールドは必ずしも重複していないか無視できます.
1、第1種の重複に対して、比較的に解決しやすくて、使う

   select distinct * from tableName 
 

重複レコードのない結果セットが得られます.
重複レコードを削除する必要がある場合(重複レコードは1つ保持)は、次の方法で削除できます.

   select distinct * into #Tmp from tableName 
  
drop table tableName
select * into tableName from #Tmp
drop table #Tmp

このような重複の原因は、テーブルの設計が不十分であるため、一意のインデックス列を追加すると解決されます.
2、このような重複問題は通常、重複記録の第1条の記録を保持することを要求し、操作方法は以下の通りである.
重複するフィールドがName、Addressであると仮定し、この2つのフィールドの一意の結果セットを得る必要があります.

   select identity(int,1,1) as autoID, * into #Tmp from tableName 
  
select min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoID
select * from #Tmp where autoID in(select autoID from #tmp2)

最後のselectでNameが得られ、Addressは重複しない結果セットが得られました(ただしautoIDフィールドが1つ増えており、実際にselect句に書くとこの列を省くことができます)
(四)
クエリの繰り返し

   select * from tablename where id in ( 
  
    select id from tablename
    group by id
    having count(id) > 1
)