[pgsql-jp: 29392] 重複レコードの削除

Makoto Komatsu eurah @ mediafront.co.jp
2003年 3月 12日 (水) 21:41:36 JST


小松です。SQLな話題を一項。

以下のようなテーブルitemsを作って、

 itemno |  name
--------+--------------
  001   | apple
  002   | orange
  003   | strawberry
  004   | grape
  005   | water melon
  006   | orange
  007   | apple
  008   | orange
  009   | pine apple
  010   | banana
  011   | apple
--------+--------------

やっと作ったところで、nameがユニークでなかった
ことに気づきます。

重複なしでアイテムを取り出すというのはよくある話で、
select distinct name from items ;
となりますが、逆に重複したアイテムだけのリストを
取り出すにはどうするのがいいんでしょうか?(問1)

僕はこんなのを考えるんですが、
select name from items group by content having count(name)>1 ;
美しくないし、邪道なんじゃないかと。
なんだかそれらしい命令を探すんだけれども、うまくいきません。
ちなみに例出のexplain値はそんなに悪くないです。

正攻法を知りたいのですが。

さらには、これらの重複レコードを削除(1件のみ残して削除)する
ことを考えてみると、aggregationが使えなくなるので、これまた
どうしたものかと悩んでしまっています。(問2)

削除するには例えば
delete from items where itemno=(・・・) ;
としたいところですが、集約演算の制約からitemnoは身動きできません。
先ほどの結果セットを使って元のテーブルからJOINしようと
すると、重複レコードはすべて出てきますし・・・。

どうすればさっくり消せるでしょうか?
悩んだ末に思いついたのが結合とdistinct使って、
select distinct on (items.name) items.itemno from items,\\
(select name from items group by content having count(name)>1) as dup \\
where items.name=dup.name ;
よしこれでitemnoのリストが出るし、これを元にdeleteで消せれば・・・(汗;

きっと簡潔な方法があるぞと思いながらも、
なんだか、はまっちゃってて。(涙;

どなたかスマートな方法教えてください。

#SQLって、検索や参照はうまくできてるけど、更新とか削除、挿入はきわめて
シンプルなんですよね。




pgsql-jp メーリングリストの案内