連関エンティティに相当するテーブルで、

複合キーにユニーク制約をかけるのを忘れて、
重複データが発生してしまいました。

■テーブル例
bookmark
|bookmark_id|bookmark_url|

bookmark_tag
|bookmark_tag_id|bookmark_id|tag_id|

tag
|tag_id|tag_name|

このbookmark_tag.bookmark_idとbookmark.tag_idへ、
複合ユニーク制約をかけるために、
先ず既存の重複レコードを削除する必要がありますが、
MySQLではDELETE文で自己相関サブクエリが使えず、
何かスマートな方法は無いかと悩んでいます。

http://dev.mysql.com/doc/refman/5.1/ja/subquery-errors.html

何か良い方法があれば教えてください。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/01/16 12:10:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:khazad-Lefty No.1

回答回数181ベストアンサー獲得回数27

ポイント27pt

MYSQLは詳しくないのですが。

MySQL 【定義命令】CREATE TABLE

によると、MYSQLは一時テーブル使えるらしいので、

create temporary table Select ~

で、一時テーブルを作成して、それとJoinすればとりあえず可能じゃないかと思います。

スマートかどうかは別として。

id:frkw2004 No.2

回答回数194ベストアンサー獲得回数21

ポイント27pt

同じフィールド構成のテーブルを作って、

Inser Into 仮テーブル Select Distinct *

で必要なデータだけ取り出しておき、元のテーブルからは全レコード削除、Indexをつけてから仮テーブルからデータを戻す。

データを戻したら仮テーブルはDropしましょう。

id:FnuLnu

一時テーブルを作る方法だと、

一旦外部キーを外さないといけないんですよね。

2009/01/09 18:51:31
id:khazad-Lefty No.3

回答回数181ベストアンサー獲得回数27

ポイント26pt

考え方としては、サブクエリの結果を一時テーブルに保存して、サブクエリのかわりにその一時テーブルを使うわけで、サブクエリでできるなら一時テーブルでもできるはずです。

とりあえず、私はMysqlあまり知らないのですが、

MySQL :: MySQL 4.1 リファレンスマニュアル :: 6.4.5 DELETE 構文とか

MySQL :: MySQL 4.1 リファレンスマニュアル :: 6.4.2.3 ANY、IN、SOME とともに使用したサブクエリ

を読んでみたら、↓の方法でいけそうな気がするのですが…。

create temporary table temp_fordelete
Select 
max(bookmark_tag_id) as maxid,
bookmark_id,tag_id,count(*)
from bookmark_tag
group by bookmark_id,tag_id
having count(*)>1

で削除対象のIDを一時テーブルに保存。その後

delete from bookmark_tag
where bookmark_tag_id
 in (Select maxid from temp_fordelete)

でそのIDに該当するデータを削除

  • id:FnuLnu
    >>このbookmark_tag.bookmark_idとbookmark.tag_idへ、
    >>複合ユニーク制約をかけるために、

    「このbookmark_tag.bookmark_idとbookmark_tag.tag_idへ、
    複合ユニーク制約をかけるために、」

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません