删除其中ID与另一个表不匹配的sql行

Mar*_*tin 146 mysql sql

我正在尝试删除mysql表中的孤立条目.

我有2个这样的表:

files:

| id | ....
------------
| 1  | ....
| 2  | ....
| 7  | ....
| 9  | ....
Run Code Online (Sandbox Code Playgroud)

blob:

| fileid | ....
------------
| 1  | ....
| 2  | ....
| 3  | ....
| 4  | ....
| 4  | ....
| 4  | ....
| 9  | ....
Run Code Online (Sandbox Code Playgroud)

fileidid列可以被用来连接表在一起.

我想删除表blobfileid无法找到的表中的所有行files.id.

因此,使用上面的示例将删除表中的行:3和4(s)blob.

OMG*_*ies 297

使用LEFT JOIN/IS NULL:

DELETE b FROM BLOB b 
  LEFT JOIN FILES f ON f.id = b.fileid 
      WHERE f.id IS NULL
Run Code Online (Sandbox Code Playgroud)

使用NOT EXISTS:

DELETE FROM BLOB 
 WHERE NOT EXISTS(SELECT NULL
                    FROM FILES f
                   WHERE f.id = fileid)
Run Code Online (Sandbox Code Playgroud)

使用NOT IN:

DELETE FROM BLOB
 WHERE fileid NOT IN (SELECT f.id 
                        FROM FILES f)
Run Code Online (Sandbox Code Playgroud)

警告

只要有可能,在事务中执行DELETE(假设支持 - IE:不在MyISAM上),这样您就可以使用回滚来恢复出现问题时的更改.

  • 一般来说,这是上述最快的? (11认同)
  • 仅供参考,这里有关于这三种方法相对效率的有用讨论:http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql / (5认同)
  • 出于某种原因,使用LEFT JOIN删除在MS SQL Server Mgmt Studio上不起作用(不确定原因;它只是抱怨LEFT JOIN).谁知道为什么会这样?它工作使用NOT EXISTS虽然:) (2认同)
  • @Pacerier - “错误”有点强。为了确保人们理解,如果 `fileid` 是 *non-nullable*,答案 *do* 有效。此外,第三个解决方案(`NOT IN`)只要求`f.id` 不可为空。大概这是一个主键,所以它会。 (2认同)
  • 对于尝试使用SQLite的人:请参阅[此答案](http://stackoverflow.com/a/4967229/786356) (2认同)

Mar*_*ith 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...*/
      )
Run Code Online (Sandbox Code Playgroud)

  • @Pacerier - 重要的一句话是“不太可能需要这条线”。“id”传统上是一个不可为空的主键。 (2认同)

Geo*_*rge 16

DELETE FROM blob
WHERE NOT EXISTS (
    SELECT *
    FROM files
    WHERE id=blob.id
)
Run Code Online (Sandbox Code Playgroud)