6

テーブルから重複レコードを削除するための洗練されたSQLステートメントを持っている人はいますか? つまり、最大 2 つまたは 3 つの重複が許可されますが、それだけですか?

現在、次のことを行う select ステートメントがあります。

delete table
from table t
left outer join (
 select max(id) as rowid, dupcol1, dupcol2
 from table
 group by dupcol1, dupcol2
) as keeprows on t.id=keeprows.rowid
where keeprows.rowid is null

これはうまくいきます。しかし、今私がやりたいのは、2 つ以上の重複がある場合にのみ、それらの行を削除することです。

ありがとう

4

4 に答える 4

7
with cte as (
  select row_number() over (partition by dupcol1, dupcol2 order by ID) as rn
     from table)
delete from cte
   where rn > 2; -- or >3 etc

クエリは、(dupcol1、dupcol2)でグループ化され、IDで並べ替えられた、各レコードの「行番号」を作成しています。実際、この行番号は、同じdupcol1とdupcol2を持つ「重複」をカウントし、ID順に番号1、2、3..Nを割り当てます。2つの「複製」だけを保持したい場合は、番号が割り当てられたものを削除する必要があります。3,4,.. Nこれは、DELLETE.. WHERE rn > 2;

この方法を使用するORDER BYと、好みの順序(たとえばORDER BY ID DESC)に合わせてを変更できます。これにより、LATESTrn=1、次に最新のものがrn=2などになります。残りは同じままDELETEです。行番号が最も大きいので、最も古いものだけが削除されます。

この密接に関連する質問とは異なり、条件がより複雑になると、CTEとrow_number()の使用がより簡単になります。適切なアクセスインデックスが存在しない場合でも、パフォーマンスに問題が生じる可能性があります。

于 2009-07-24T01:01:44.760 に答える
3

HAVINGあなたの友だちです

select id, count(*) cnt from table group by id having cnt>2

于 2009-07-24T00:49:56.910 に答える