MySQL绕过错误1093

Posted

技术标签:

【中文标题】MySQL绕过错误1093【英文标题】:MySQL Getting around error 1093 【发布时间】:2011-05-27 22:53:01 【问题描述】:

错误 1093 指出,如果您的子查询查询您要从中删除的表,则您无法使用子查询进行 UPDATE 或 DELETE。

所以你不能这样做

delete from table1 where id in (select something from table1 where condition) ;

好的,解决该限制的最佳方法是什么,(假设您确实需要子查询来执行删除并且不能完全消除自引用子查询?)

编辑:

以下是感兴趣的人的查询:

mysql> desc 邻接; +---------+---------+------+------+---------+------ -+ |领域 |类型 |空 |钥匙 |默认 |额外 | +---------+---------+------+------+---------+------ -+ |家长 |整数(11) |否 |优先级 |空 | | |孩子|整数(11) |否 |优先级 |空 | | |路径长度 |整数(11) |否 | |空 | | +---------+---------+------+------+---------+------ -+ -- 查询将 ——告诉我所有的孩子 ——别再想我的老父母了 ——仍然是他们的父母 从邻接中删除 父母在哪里 ( -- 我所有的父母,祖父母 选择父母 从邻接 孩子=@我 和父母!=@我 ) ——只涉及我的关系 -- 关心我孩子的祖父母 和孩子在 ( ——带上我所有的孩子 选择孩子 从邻接 哪里父母=@我 ) ;

所以到目前为止我尝试的是创建一个名为 adjsToDelete 的临时表

create temporary table adjsToRemove( parent int, child int ) ;
insert into adjsToRemove...

所以现在我有一个要删除的关系集合,其中父/子对各自唯一标识要删除的行。但是我现在如何从邻接表中删除每个 pair

看来我需要为adjacencies 中的每个条目添加一个唯一的auto_incremented 键,对吗?

【问题讨论】:

你尝试过使用 nolock 吗? 你想做什么?查询是什么? a1ex07 的答案(使用连接删除)在大型表上的性能比使用双嵌套子查询的变通办法更好。 【参考方案1】:

在http://bugs.mysql.com/bug.php?id=6980 中找到的对我有用的解决方法是为将返回项目的子查询创建别名。所以

delete from table1 where id in 
  (select something from table1 where condition)

将改为

delete from table1 where id in
  (select p.id from (select something from table1 where condition) as p)

【讨论】:

【参考方案2】:

你可以的

delete t1,t2 
FROM  table1 t1  
INNER JOIN 
table1 t2 ON (t2.something = t1.id);

对于问题中的查询,这应该是等效的:

delete A
from adjacencies A
join adjacencies B ON A.parent = B.parent AND B.child=@me AND B.parent != @me
join adjacencies C ON A.child = C.child AND C.parent=@me

【讨论】:

您可以在删除时使用内连接。 那么有人可以澄清如何使用此响应来执行问题中列出的子查询吗? 未经测试,但类似于DELETE a1 FROM adjacencies AS a1 INNER JOIN adjacencies AS a2 ON a1.id=a2.id WHERE a1.parent=a2.parent and a2.child=@me and a2.parent!=@me; @a1ex07 我已经更新了一个(未经测试的)示例,说明如何解决原始查询【参考方案3】:

Currently, you cannot delete from a table and select from the same table in a subquery - details

你只是不能不能指定要删除的目标表

我的一种解决方法:MySQL DELETE FROM with subquery as condition

【讨论】:

所以看起来我需要在我的邻接表中添加一个 ID 列,例如“创建表邻接(id int PRIMARY KEY, parent int, child int, pathLen int)”——我无法执行此解决方案否则 - 对吧? @bobobobo - 是的,您可以创建一个额外的列,并使用匹配的 ID 更新它,如果额外的列包含 NON-ZERO 值,则删除。 或者创建一个包含所有ID的快照表。我更喜欢方法二,因为它没有涉及当前的工作数据。【参考方案4】:

简化:

-- Collect ids
CREATE TEMPORARY TABLE cleanup_lookup AS 
SELECT id FROM table1 WHERE condition;

-- Delete the selected records
DELETE t FROM table1 t INNER JOIN cleanup_lookup l ON t.id = l.id;

-- Temporary tables get dropped when the connection is closed.

【讨论】:

【参考方案5】:

你可以毫不犹豫地使用这个。

您的查询:

delete from table1 
where id in (select something from table1 where condition);

更新查询:

DELETE FROM table1 
WHERE id IN (SELECT * 
             FROM 
                 (SELECT MIN(id) FROM table1 GROUP BY Column2) x);

这里Column2 是您要查找重复记录的列。

【讨论】:

以上是关于MySQL绕过错误1093的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 更新错误 1093

错误 1093:MySQL 无法在 FROM 子句中指定更新的目标表

mysql Error1093错误

MySql 错误 1093 尝试使用两个数据库和两个表进行更新

无法运行查询给出 mySQL 错误 #1093 - 您无法在 FROM 子句中指定目标表“成员”进行更新 [重复]

Mysql 错误:1093 - 无法在 FROM 子句中指定要更新的目标表