IDが一致しないSQL行を別のテーブルから削除する


160

mysqlテーブルの孤立したエントリを削除しようとしています。

次のような2つのテーブルがあります。

テーブルfiles

| id | ....
------------
| 1  | ....
| 2  | ....
| 7  | ....
| 9  | ....

テーブルblob

| fileid | ....
------------
| 1  | ....
| 2  | ....
| 3  | ....
| 4  | ....
| 4  | ....
| 4  | ....
| 9  | ....

一緒にテーブルを結合するために列を使用することができます。fileidid

私は、テーブル内のすべての行を削除したいblob場所fileidのテーブルで見つけることができませんfiles.id

したがって、上記の例を使用すると、行が削除されます:blobテーブルの3&4(s)。


1
s を使用している場合は、2番目の回答に進んでくださいnull
Pacerier、2015

回答:


326

LEFT JOIN / IS NULLの使用:

DELETE b FROM BLOB b 
  LEFT JOIN FILES f ON f.id = b.fileid 
      WHERE f.id IS NULL

NOT EXISTSの使用:

DELETE FROM BLOB 
 WHERE NOT EXISTS(SELECT NULL
                    FROM FILES f
                   WHERE f.id = fileid)

NOT INの使用:

DELETE FROM BLOB
 WHERE fileid NOT IN (SELECT f.id 
                        FROM FILES f)

警告

問題が発生した場合にロールバックを使用して変更を元に戻すことができるように、可能な場合は常にトランザクション内でDELETEを実行します(サポートされている場合-IE:MyISAMではありません)。


12
一般的に、上記の中で最も速いのはどれですか。
Hampus Brynolf

2
何らかの理由で、LEFT JOINを使用した削除はMS SQL Server Mgmt Studioでは機能しませんでした(理由は不明です。LEFTJOINに不満があっただけです)。誰もがその理由を知っていますか?それは:)していないがEXISTS使用して働いていた
アンナ

5
FYI、ここではこれらの3つの方法の相対的な効率の有益な議論があります:explainextended.com/2009/09/18/...
moustachioは

2
@Pacerier-「間違っている」は少し強いです。人々が理解していることを確認するために、null可能ない場合、答え機能します。また、3番目のソリューション()では、nullを指定できないことのみが必要です。おそらくそれが主キーなので、そうでしょう。fileidNOT INf.id
ToolmakerSteve 2016

2
SQLiteを使用してこれを
試す

26
DELETE FROM blob 
WHERE fileid NOT IN 
       (SELECT id 
        FROM files 
        WHERE id is NOT NULL/*This line is unlikely to be needed 
                               but using NOT IN...*/
      )

何が「/ *この行が必要になることはほとんどありませんが、NOT IN ... * /使用」を意味するはず?
Pacerier、2015

1
@Pacerier- NOT IN (NULL)空の結果セットを返すため、NULLを除外する必要があります。しかし、idおそらく列はおそらくnull可能ではないので、「必要になる可能性は低い」
Martin Smith、

すごいキャッチ。だからomgponiesの答えは間違っています!not in(null)かなり論理的ですが、なぜ機能しないのですか?その背後にある理論的根拠は何ですか?
Pacerier、2015


1
@bunkerdive次に、データベース名を含む3つの部分のオブジェクト名を使用します。
マーティン・スミス

17
DELETE FROM blob
WHERE NOT EXISTS (
    SELECT *
    FROM files
    WHERE id=blob.id
)

1
私はそこだと思うfiles.idblob.fileid。クエリがエラーになると思います。
JWW

-8
delete from table1 t1 
    WHERE not exists (select id from table2 where related_field_in_t2=t1.id) 
    AND not exists (select id from table3 where related_field_in_t3=t1.id) 
    AND not exists (select id from table4 where related_field_t4=t1.id) 
    AND not exists (select id from table5 where related_field_t5=t1.id);

3
1.投稿されたコンテキストでの質問への回答を試みていない。2.説明はありません(Stackoverflowではコードのみの回答は価値が低くなります)。3. NOT EXISTSは9年前に既に投稿されています。4. MySQLキーワードにすべて大文字を使用するというベストプラクティスを推進していません。言い換えれば、ここに保持する価値があるものは何もありません。これが私がこの投稿を削除することにも投票した理由です。
mickmackusa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.