人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

連関エンティティに相当するテーブルで、
複合キーにユニーク制約をかけるのを忘れて、
重複データが発生してしまいました。

■テーブル例
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

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

●質問者: FnuLnu
●カテゴリ:ウェブ制作
✍キーワード:.book bookmark DELETE MySQL tag
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● khazad-Lefty
●27ポイント

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

MySQL 【定義命令】CREATE TABLE

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

create temporary table Select ?

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

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


2 ● ふるるP
●27ポイント

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

Inser Into 仮テーブル Select Distinct *

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

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

◎質問者からの返答

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

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


3 ● khazad-Lefty
●26ポイント

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

とりあえず、私は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に該当するデータを削除

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ