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

Posted

技术标签:

【中文标题】从另一个表中删除 ID 不匹配的 sql 行【英文标题】:Delete sql rows where IDs do not have a match from another table 【发布时间】:2011-03-23 23:37:36 【问题描述】:

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

我有 2 个这样的表:

files:

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

blob:

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

fileidid 列可用于将表连接在一起。

我想删除表 blob 中在表 files.id 中找不到 fileid 的所有行。

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

【问题讨论】:

如果您使用的是nulls,请跳至第二个答案 【参考方案1】:

使用 LEFT JOIN/IS NULL:

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

使用不存在:

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 上),以便在出现问题时使用回滚恢复更改。

【讨论】:

这通常是上述最快的? 由于某种原因,使用 LEFT JOIN 删除在 MS SQL Server Mgmt Studio 上不起作用(不知道为什么;它只是抱怨 LEFT JOIN)。有谁知道这是为什么?它虽然使用 NOT EXISTS 工作:) 仅供参考,这里对这三种方法的相对效率进行了有用的讨论:explainextended.com/2009/09/18/… @Pacerier - “错误”有点强烈。为确保人们理解,如果fileid不可为空,答案确实有效。此外,第三种解决方案 (NOT IN) 仅要求 f.id 不可为空。大概这是一个主键,所以它会。 对于尝试使用 SQLite 进行此操作的人:请参阅 this answer【参考方案2】:
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 - NOT IN (NULL) 返回一个空结果集,因此需要排除 NULL。但是id 列可能无论如何都不能为空,因此“不太可能需要” @Pacerier because unknown and anything is either false or unknown and can never evaluate to true @bunkerdive 然后使用包含数据库名称的三部分对象名称。 @Pacerier - 重要的句子是“这条线不太可能需要”。 id 传统上是不可为空的主键。【参考方案3】:
DELETE FROM blob
WHERE NOT EXISTS (
    SELECT *
    FROM files
    WHERE id=blob.id
)

【讨论】:

我认为有files.idblob.fileid。我猜你的查询会出错。

以上是关于从另一个表中删除 ID 不匹配的 sql 行的主要内容,如果未能解决你的问题,请参考以下文章

Mysql通过ID从另一个表中删除一个表

如何删除EXCEL表中的大量数据行,要删除的行数大概8万

sql 一个表里已经 有20行数据 ,然后要从另一个表里随机抽取20条 覆盖掉之前的数据

SQLAlchemy:从另一个查询的结果中查找表中的所有匹配行

如果每个工作表中的字符串匹配,则修复删除行

sql中怎么才能实现两张表 数据自动匹配