MySQLの複数のテーブルから削除する方法は?


116

いくつかのテーブルから一度に削除しようとしています。私は少し研究をして、これを思いつきました

DELETE FROM `pets` p,
            `pets_activities` pa
      WHERE p.`order` > :order
        AND p.`pet_id` = :pet_id
        AND pa.`id` = p.`pet_id`

ただし、このエラーが発生しています

Uncaught Database_Exception [1064]:SQL構文にエラーがあります。MySQLサーバーのバージョンに対応するマニュアルで、 'p、pets_activitiespa ...の近くで使用する正しい構文を確認してください...

これまでクロステーブルの削除を行ったことがないので、今のところ経験がなく、行き詰まっています。

何が悪いのですか?

回答:


204

ステートメントでa JOINを使用しDELETEます。

DELETE p, pa
      FROM pets p
      JOIN pets_activities pa ON pa.id = p.pet_id
     WHERE p.order > :order
       AND p.pet_id = :pet_id

代わりにあなたは使うことができます...

DELETE pa
      FROM pets_activities pa
      JOIN pets p ON pa.id = p.pet_id
 WHERE p.order > :order
   AND p.pet_id = :pet_id

...からのみ削除する pets_activities

参照してくださいこれを

単一のテーブルの削除については、まだ参照整合性で、とやって、他の方法がありますEXISTSNOT EXISTSINNOT INおよびなどしかし、あなたが前にエイリアスを削除するためにどのテーブルから指定した場所の上1 FROM節は、いくつかのかなりタイトで、あなたを得ることができますより簡単にスポット。私はEXISTS99%のケースに問い合わせる傾向があり、このMySQL構文が1日かかるのは1%です。


7
6つの大きなテーブル(約15,000行)を結合してこの「1つのクエリをすべて削除」を試してみましたが、クエリは6つのテーブルの63行を削除するのに155秒かかりました:O
KlemenTušarJul

1
@cadmanこれが正解です。それを使用することに反対の議論があるかもしれませんが、それは時々非常に役に立ちます
サイモン・クリスチャン

1
+1質問は「どうすべきか」ではなく「方法」だったので、これは正解です。ただし、1%について聞きたいと思います。これが望ましい状況は1つとは思えないからです。
エリックロバートソン

2
@techouse、インデックスに参加してフィルタリングしましたか?15k x 15k x 15k x 15k 15k x 15kは1100万です。SELECT同じように長い時間がかかりましたか?
Paul Draper

6
LEFT JOINを使用することもできます。これは、2番目のテーブルに一致するエントリがない場合に役立ちます。そうでない場合、何も削除されません。
Lexib0y 2015年

20

これが表示されますが間の単純な親/子関係することがあるのでpetsそしてpets_activities、あなたは削除カスケードを使用して、外部キー制約を作成したほうが良いでしょう。

これにより、pets行が削除されると、pets_activitiesそれに関連付けられている行も自動的に削除されます。

その後、クエリは単純になります。

delete from `pets`
    where `order` > :order
      and `pet_id` = :pet_id

3
@Erick、参照整合性を設定している場合、カスケード削除は、それ自体で削除する以上の問題を引き起こすことはありません。これはマッピングpapために適切な子であることはすでに知っていid/pet_idます。
paxdiablo 2010

14
ええと、皆さんはあなた自身の考えを持っていますが、DBMSの多くの能力を割り引いているようです。カスケード削除は、トリガー、ストアドプロシージャ、または制約と同じくらいデータ管理の一部であり、何をしているのかわからない場合にのみ危険です。それでも、この点についてはこれ以上議論しません。反対することに同意する必要があるだけです。
paxdiablo 2010

8
エリック、今あなたは私の興味をそそりました。制約なしでデータベース内のデータの整合性をどのように保証しますか?
paxdiablo 2010

4
@エリック氏は、「私はトリガー、ストアドプロシージャ、または制約も使用しません。」ああ、あなたはエクセルを使います。:-)
james.garriss 2013

4
これについてフォローアップしたいだけです。この状況でカスケードを削除する立場を変更しました。私はそれらを使用する新しいSQL環境の一部であり、それらをうまく使用し、それらは非常に整理されていました。このシステムでは、これらのカスケードを配置することは非常にうまく機能しました。孤立したデータを確実に防ぎ、危険ではありませんでした。問題は、データベースを使用するすべての人が、それらを安全に使用する方法を理解する必要があることです。しかし、ジュニア開発者が管理されていないデータベースの変更を行うと、常にリスクが生じます。
エリックロバートソン


3

現在テストするmysqlデータベースはありませんが、from句の前に何を削除するかを指定してみましたか?例えば:

DELETE p, pa FROM `pets` p,
        `pets_activities` pa
  WHERE p.`order` > :order
    AND p.`pet_id` = :pet_id
    AND pa.`id` = p.`pet_id`

あなたが使用した構文は、mysqlの新しいバージョンに限定されていると思います。


1
そのクエリは正常に実行されましたが、行は削除されませんでした(ただし、そうする必要があると思います)。
アレックス、

2

構文は私には正しいようです...使用するように変更してみてくださいINNER JOIN...

見ていこれを


7
リンクが正しいため、実際のソリューションを含めなかったのは残念です。
mycroes

1

2017年にこれを読んでいる人にとって、これは私が同じようなことをした方法です。

DELETE pets, pets_activities FROM pets inner join pets_activities
on pets_activities.id = pets.id WHERE pets.`order` > :order AND 
pets.`pet_id` = :pet_id

一般に、複数のテーブルから行を削除するために、私が従う構文は以下のとおりです。ソリューションは、2つのテーブル間に何らかの関係があるという前提に基づいています。

DELETE table1, table2 FROM table1 inner join table2 on table2.id = table1.id
WHERE [conditions]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.