从另一个表中删除 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 | ....
fileid
和 id
列可用于将表连接在一起。
我想删除表 blob
中在表 files.id
中找不到 fileid
的所有行。
因此,使用上面的示例将删除 blob
表中的行:3 和 4(s)。
【问题讨论】:
如果您使用的是null
s,请跳至第二个答案。
【参考方案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.id
和blob.fileid
。我猜你的查询会出错。以上是关于从另一个表中删除 ID 不匹配的 sql 行的主要内容,如果未能解决你的问题,请参考以下文章
sql 一个表里已经 有20行数据 ,然后要从另一个表里随机抽取20条 覆盖掉之前的数据