2011-06-23 5 views
3

私は、以下のように重複したレコードを含むテーブル名TABLE1があります。この場合Oracle PL/SQL - SQLテーブルの複数の重複レコードを削除するにはどうすればよいですか?

ID TYPE AMOUNT NUMBER  DATE 
--- ---- ------ ------ --------- 
1 AAA 10.00 AAA123 22-JUN-11 
2 AAA 2.00 AAA123 22-JUN-11 
3 AAA 10.00 AAA123 22-JUN-11 
4 AAA 2.00 AAA123 22-JUN-11 
5 AAA 10.00 AAA123 22-JUN-11 
6 AAA 2.00 AAA123 22-JUN-11 
7 AAA 10.00 AAA123 22-JUN-11 
8 AAA 2.00 AAA123 22-JUN-11 
... ...  ... ...  ... 
100 AAA 10.00 AAA123 22-JUN-11 
101 AAA 2.00 AAA123 22-JUN-11 

を、私は2つの金額(10.00 PL/SQL経由でSQLまたは/を使用することを除いて、すべての重複組み合わせの行を削除したいです2.00)。加えて、異なる量を含有する重複recordesは、以下に示すように二つ以上であり得る:

ID TYPE AMOUNT NUMBER  DATE 
--- ---- ------ ------ --------- 
1 AAA 10.00 AAA123 22-JUN-11 
2 AAA 2.00 AAA123 22-JUN-11 
3 AAA 15.00 AAA123 22-JUN-11 
4 AAA 25.50 AAA123 22-JUN-11 
5 AAA 10.00 AAA123 22-JUN-11 
6 AAA 2.00 AAA123 22-JUN-11 
7 AAA 15.00 AAA123 22-JUN-11 
8 AAA 25.50 AAA123 22-JUN-11 
... 

上記の例では、私は量が4つのレコード(10.00ままであるべきであるのみ4〜8のうちのレコードを削除する必要があります、2.00、15.00および25.50)。言い換えれば、私は1つのテーブルに複数の重複グループを持っています(1つは2レコード、もうひとつは4レコードなど) - 複数のレコードが存在する複数のレコードです。

+0

だから何の列がDUPLICATESに貢献?金額のみ? – Chandu

+0

コミュニティでは、PLSQLに実際にSQLのみを使用している場合にタグを付けていません。オラクルのどのバージョンですか? –

答えて

2

DATE列は、より多くの情報を必要とする唯一の列です。そうでなければ使用:

DELETE FROM YOUR_TABLE 
WHERE EXISTS (SELECT NULL 
       FROM YOUR_TABLE t 
       WHERE t.type = YOUR_TABLE.type 
        AND t.amount = YOUR_TABLE.amount 
        AND t.number = YOUR_TABLE.number 
        AND t.date = YOUR_TABLE.date 
      GROUP BY t.type, t.amount, t.number, t.date 
       HAVING MIN(t.id) != YOUR_TABLE.id) 

YOUR_TABLE.カラム参照が削除がで実行される外側YOUR_TABLE、テーブルを参照します。これはそれに相関サブクエリ効果を与えますが、EXISTSはそれほど機能しません。

3

これを試してください:あなたが従うことができる

DELETE 
    FROM TABLE1 
    WHERE ROWID IN 
    (
     SELECT ROW_ID_VAL 
      FROM 
      (
       SELECT a.*, 
         RANK() OVER(PARTITION BY AMOUNT ORDER BY ID DESC) RN, ROWID row_id_val 
        FROM TABLE1 a 
      ) 
      WHERE rn <> 1 
    ) 
+0

この状況では 'ROW_NUMBER'が良い選択でしょうか? –

+0

@OMG Pointes:私はIDを使ってウィンドウ内のデータを注文しているので、Idフィールドは一意であり、RANK shuoldはまだ問題ありません。 – Chandu

+0

真実 - 気にしないで、Before Coffee(tm) –

1

一つの方法は、以下の通りである:

各行はユニークな(row id)を持っています。もちろん、複製された行を識別し、(row id)に基づいて複製された行を削除することができます。ただ、重複した行のIDを明らかにするために、次のSELECTの文を入力します。

SELECT rowid from table_name;

0
DECLARE 

BEGIN 

    for rec_ in (
       SELECT type, amount, number, date , count(1) record_count 
        FROM table 1 
        GROUP BY type, amount, number, date 
       HAVING count(1) > 1) loop 

     counter_ := 0; 

     for rec2_ in (select * from table1 where rec_.type = type 
              and rec_.amount = amount 
              and rec_.number = number 
              and rec_.date = date) loop 

      counter_ := counter_ + 1;    
      exit when counter_ = rec_.record_count; 
      delete from table1 where id = rec2_.id; 
     End loop; 

    end loop; 
END; 
関連する問題