【问题标题】:MySQL Error You can't specify target table for update in FROM clauseMySQL 错误您不能在 FROM 子句中指定要更新的目标表
【发布时间】:2015-09-15 11:34:30
【问题描述】:

我的数据库中有 2 个表 MST_customer 和 TRN_sales 条目已损坏。下一个查询返回损坏的条目:

SELECT TRN_sales.cust_no 
FROM MST_customer 
RIGHT OUTER JOIN TRN_sales 
ON MST_customer.cust_no = TRN_sales.cust_no 
WHERE MST_customer.cust_name IS NULL;

我试图删除它们正在执行:

DELETE FROM mydbB.TRN_sales
WHERE TRN_sales.cust_no IN (
  SELECT TRN_sales.cust_no
  FROM MST_customer
  RIGHT OUTER JOIN TRN_sales
  ON MST_customer.cust_no = TRN_sales.cust_no
  WHERE MST_customer.cust_name IS NULL
);

但我得到下一个错误:

You can't specify target table 'TRN_sales' for update in FROM clause

我该如何解决这个问题?

【问题讨论】:

    标签: mysql subquery sql-delete


    【解决方案1】:

    为了更加“安全”,您应该指定要删除的表(此处为别名s):

    DELETE s FROM TRN_sales s
    LEFT JOIN MST_customers ON MST.cust_no=TRN.cust_no
    WHERE MST.cust_name IS NULL;
    

    我个人认为,这个LEFT JOIN 更容易阅读,当然你也可以用你的RIGHT JOIN 版本做同样的事情。

    【讨论】:

    • @cars10:请您详细说明“delete s”如何比“delete TRN.*”更安全.....是的,左连接更具可读性,但我刚刚处理了 Rin 的查询,以便他感觉很简单,就像他的查询一样...但是如果您使用左连接或右连接,两者都没有问题。
    • 您好 Zafar,您的答案是(并且一直是)100% 正确!当我写我的答案时,我误读了您的TRN.* 指的是整个数据库。情况并非如此,因为您只提到有问题的销售表是完全正确的。因此,从我的角度来看,您的答案仍然是正确的答案,并且应该成为此处首次出现的“选择的答案”。我保留答案的唯一原因是用LEFT JOIN 而不是RIGHT JOIN 显示另一种方法。无论如何,我只是“升级”了你的帖子...... ;-)
    • @cars10: 一点也不,我只是好奇 alias.* 是否有任何重大影响,并且只是在 join 下删除别名。 :)
    【解决方案2】:

    为什么你不试试下面-

    DELETE TRN.*
    FROM MST_customer MST
    RIGHT OUTER JOIN TRN_sales TRN
    ON MST.cust_no = TRN.cust_no 
    WHERE MST.cust_name IS NULL;
    

    注意:为安全起见,请在执行此查询之前备份两个表。

    【讨论】:

    • 您不需要*DELETE TRN FROM ... 也可以。
    猜你喜欢
    • 2011-05-24
    • 2019-11-16
    • 1970-01-01
    • 2015-07-10
    • 2014-07-09
    • 2012-03-06
    相关资源
    最近更新 更多