2017-11-27 7 views
1

この表に一意のキーが必要なため、これらの6つのフィールドを含むすべての重複を削除するためのクエリを実行するように求められました。forループで重複したOracle SQLの削除

私はテーブルの中で最大のIDを持つものを残し、それ以外のものはすべて削除する必要があります。私はそれを行うためにfor-loopを使用することの提案に従って、次のコードを思いついた。

begin 
    for rec in (
     select max(id), attribute, product, partner, pr_group, contact_person, branch, count(1) cnt 
     from co_attribute 
     where attribute = 100000034 and product = 100252046 
     group by attribute, product, partner, pr_group, contact_person, branch 
     having count(1) > 1 
) loop 
     delete from co_attribute 
     where (attribute = rec.attribute 
      or (attribute is null and rec.attribute is null)) 
      and (product = rec.product 
      or (product is null and rec.product is null)) 
      and (partner = rec.partner 
      or(partner is null and rec.partner is null)) 
      and (pr_group = rec.pr_group 
      or(pr_group is null and rec.pr_group is null)) 
      and (contact_person = rec.contact_person 
      or(contact_person is null and rec.contact_person is null)) 
      and (branch = rec.branch 
      or(branch is null and rec.branch is null)) 
      and (max(id) < rec.id) 
      ; 
     dbms_output.put_line(
    'Deleting duplicates '   || 
    ' |attribute: ' || rec.attribute  || 
    ', product: '  || rec.product  || 
    ', partner: '  || rec.partner  || 
    ', pr_group: '  || rec.pr_group || 
    ', contact_person: ' || rec.contact_person || 
    ', branch: '  || rec.branch  || 
    ', id: '  || rec.id   || 
    ', deleting row: ' || sql%rowcount 
); 
    end loop; 
end; 
/

このスクリプトをテストしている間は、私はデータベース全体を台無しにしていません。これは私に次のエラーを与える:

Error report - 
ORA-06550: line 22, column 15: 
PL/SQL: ORA-00934: group function is not allowed here 
ORA-06550: line 9, column 7: 
PL/SQL: SQL Statement ignored 
06550. 00000 - "line %s, column %s:\n%s" 
*Cause: Usually a PL/SQL compilation error. 
*Action: 

だから私は2つの質問がある:最初に、どのように私はこの問題を解決し、これが最も効果的な方法であるのですか?

編集:私はコメントしてこっちを示唆し、いくつかの変更の一部以下にそれを固定

+0

変更は 'max_id'として選択MAX(ID)'に 'MAX(ID)を選択します。次に、 'と(max(id) rec.id)'に変更してください。これはOKです。 – g00dy

+3

もし私があなただったら、ROWIDで行を削除します。つまり、削除する必要のある行、つまりROWIDをカーソルが返す必要があります。その場合、delete文は非常にシンプルでなければなりません。また、何十億と何十億というレコードであれば、最初はユニークなものを抽出して別のテーブルに入れ、元のものを切り捨ててから、以前に保存したユニークなものを挿入します。 – g00dy

答えて

0

することにより、グループ内のidフィールドを削除!最初にをmax(id) maxidに変更しました。max(id) < rec.id~id < rec.maxidmaxidrecの部分であり、削除クエリではないため変更されました。

ありがとうございました!あなたがテーブルの上に最大のIDを持つものを残して、他のすべてのものを削除するための文の下に使用することができます

2

delete co_attribute a 
where 
    a.id < 
    any (select b.id 
      from co_attribute b 
     where (a.attribute = b.attribute or (a.attribute is null and b.attribute is null)) 
      and (a.product = b.product or (a.product is null and b.product is null)) 
      and (a.partner = b.partner or (a.partner is null and b.partner is null)) 
      and (a.pr_group = b.pr_group or (a.pr_group is null and b.pr_group is null)) 
      and (a.contact_person = b.contact_person or (a.contact_person is null and b.contact_person is null)) 
      and (a.branch = b.branch or (a.branch is null and b.branch is null)) 
     ); 
関連する問題