MySQL 解决错误 1093

发布于 2024-10-08 05:20:29 字数 1436 浏览 3 评论 0原文

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

所以你不能这样做好

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

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

编辑:

这是感兴趣的人的查询:

mysql> desc adjacencies ;
+---------+---------+------+-----+---------+-------+
| Field   | Type    | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| parent  | int(11) | NO   | PRI | NULL    |       |
| child   | int(11) | NO   | PRI | NULL    |       |
| pathLen | int(11) | NO   |     | NULL    |       |
+---------+---------+------+-----+---------+-------+



-- The query is going to
-- tell all my children to
-- stop thinking my old parents
-- are still their parents

delete from adjacencies
where parent in 
(
-- ALL MY PARENTS,grandparents
  select parent
  from adjacencies
  where child=@me
  and parent!=@me
)

-- only concerns the relations of my
-- grandparents WHERE MY CHILDREN ARE CONCERNED
and child in
(
  -- get all my children
  select child
  from adjacencies
  where parent=@me
)

;

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

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

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

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

Error 1093 states that you can't UPDATE or DELETE using a subquery if your subquery queries the table you are deleting from.

So you can't do

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

Ok, what's the best way to work around that restriction, (assuming you really do need to subquery to perform the delete and cannot eliminate the self referencing subquery entirely?)

Edit:

Here's the query for those who are interested:

mysql> desc adjacencies ;
+---------+---------+------+-----+---------+-------+
| Field   | Type    | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| parent  | int(11) | NO   | PRI | NULL    |       |
| child   | int(11) | NO   | PRI | NULL    |       |
| pathLen | int(11) | NO   |     | NULL    |       |
+---------+---------+------+-----+---------+-------+



-- The query is going to
-- tell all my children to
-- stop thinking my old parents
-- are still their parents

delete from adjacencies
where parent in 
(
-- ALL MY PARENTS,grandparents
  select parent
  from adjacencies
  where child=@me
  and parent!=@me
)

-- only concerns the relations of my
-- grandparents WHERE MY CHILDREN ARE CONCERNED
and child in
(
  -- get all my children
  select child
  from adjacencies
  where parent=@me
)

;

So what I've tried so far is creating a temporary table called adjsToDelete

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

So now I have a collection of relations to delete, where the parent/child pairs each uniquely identify a row to delete. But how do I delete each pair from the adjacencies table now?

It seems I need to add a unique auto_incremented key to each entry in adjacencies, is that right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

可遇━不可求 2024-10-15 05:20:29

解决方法,可在 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)

A workaround, found in http://bugs.mysql.com/bug.php?id=6980, that worked for me is to create an alias to the sub query that will return the items. So

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

would be changed to

delete from table1 where id in
  (select p.id from (select something from table1 where condition) as p)
海未深 2024-10-15 05:20:29

您可以执行

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

You can do

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

For the query in the question, this should be equivalent:

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
姜生凉生 2024-10-15 05:20:29

目前,您无法在子查询中从表中删除并从同一个表中进行选择
- 详细信息

你不能无法指定目标表对于删除

我的解决方法之一: MySQL DELETE FROM以子查询为条件

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

You just cannot cannot specify target table for delete

one of my workaround : MySQL DELETE FROM with subquery as condition

夏天碎花小短裙 2024-10-15 05:20:29

简化:

-- 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.

Simplified:

-- 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.
想你只要分分秒秒 2024-10-15 05:20:29

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

您的查询:

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 是您要查找重复记录的列。

You can use this one without hesitation.

Your query:

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

Updated query:

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

Here Column2 is column on which you want to find duplicate records.

夜光 2024-10-15 05:20:29
DELETE FROM `table1` 
WHERE id IN (SELECT * 
             FROM 
                 (select max(`id`)FROM table1 group by Column2 having count(*) >1) x);

这里 Column2 是您要查找重复记录的列(它可能有多个列)。

这只会删除重复的记录。

DELETE FROM `table1` 
WHERE id IN (SELECT * 
             FROM 
                 (select max(`id`)FROM table1 group by Column2 having count(*) >1) x);

Here Column2 is a column on which you want to find duplicate records (it may have multiple columns).

This will delete only duplicate records.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文