MYSQL更新,其中选择子查询错误

MYSQL更新,其中选择子查询错误,mysql,select,subquery,Mysql,Select,Subquery,我在让选择子查询处理更新时遇到问题。我正在尝试以下方法: UPDATE foo SET bar=bar-1 WHERE baz= ( SELECT baz FROM foo WHERE fooID='1' ) 其中foo是主键为fooID的表名。bar和baz的类型为INT。执行此操作时,我得到以下错误: Error: A query failed. You can't specify target table 'foo

我在让选择子查询处理更新时遇到问题。我正在尝试以下方法:

UPDATE foo
   SET bar=bar-1
 WHERE baz=
      (
       SELECT baz
       FROM foo
       WHERE fooID='1'
      )
其中foo是主键为fooID的表名。bar和baz的类型为INT。执行此操作时,我得到以下错误:

Error: A query failed. You can't specify target table 'foo' for update 
in FROM clause

由于错误1093错误1093 ER\U更新表\U使用SQLSTATE=HY000。 解决方法是创建一个临时表

CREATE TEMPORARY table foo_bak (SELECT baz from foo WHERE fooID='1');

UPDATE foo
  SET foo.bar=foo.bar-1
WHERE foo.baz =
  (
    SELECT baz
    FROM foo_bak
  );

DROP TABLE foo_bak;

据我所知,在更新表时,Mysql会锁定它以进行安全更新。无法选择数据并在尝试时更新同一个表

这些文本应该对你有帮助

由此

此错误的原因是,当您在内部select中使用同一个表作为更新条件时,MySQL不允许对该表进行更新。 本文接着提供了一种解决方案,即使用临时表

CREATE TEMPORARY table foo_bak (SELECT baz from foo WHERE fooID='1');

UPDATE foo
  SET foo.bar=foo.bar-1
WHERE foo.baz =
  (
    SELECT baz
    FROM foo_bak
  );

DROP TABLE foo_bak;
使用此示例,您的更新应如下所示:

update foo
set bar = bar - 1
where baz in
(
  select baz from
  (
    select baz
    from foo
    where fooID = '1'
  ) as arbitraryTableName
)

在某些情况下,您还可以利用MySQL变量。e、 g:

SET @id1 = (SELECT id FROM foo WHERE name = 'parent');
UPDATE foo SET parent_id = @id1 WHERE name = 'emails';

可能重复,但子查询不应该是不相关的吗?i、 首先运行内部查询,然后运行外部查询。。。这是一个能够运行的非常有用的查询,但它不被允许似乎很奇怪是的,我试着给所有的东西命名,但是没有运气。。似乎无法在子查询中使用相同的表。。。是的,如果我没记错的话,PostgreSQL允许这样做。Dwb的解决方案更简洁。如果你创建一个临时表,你不需要删除它,因为当脚本结束时,临时表会自动删除。我一有机会就会重新访问它,但这只是一个未经测试的想法,我想我会抛弃它:解决OP错误的更干净的方法不是不使用任何子选择,而是在更新查询中加入foo本身吗?这里的嵌套SELECT语句是有效的,自从看到您的答案后,我一直使用它们来解决这种情况,但它们非常粗糙-如果联接有效,它感觉像是“正确”的解决方案。我同意嵌套SELECT可能不是最好的解决方案。除了OP提出的解决方案之外,我没有考虑其他解决方案。加入似乎很好,但是对于SQL,我通常不愿意说一个有效的解决方案是“正确的”,另一个是“不正确的”。我尝试了另一种方法,它也可以工作,更新foo f,从foo中选择baz,其中fooID='1'a set f.bar=f.bar-1其中f.baz=a.baz。我的mysql版本是5.6.27-0ubuntu0.14.04.1-log@DWB至少10.3取消了这一限制