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

Posted

技术标签:

【中文标题】MySQL 无法在 FROM 子句中指定更新的目标表【英文标题】:MySQL can’t specify target table for update in FROM clause 【发布时间】:2014-11-20 08:44:25 【问题描述】:

我知道这里有类似的帖子,但我还没有找到适合我的问题的帖子。

mysql 表 oxarticles 中,我有从外部程序导入的文章。该程序将每篇文章作为父文章和变体发送两次,其中一些列包含附加数据。

我想对表格进行规范化,将附加的列数据写入父文章中。

我的更新查询如下所示:

UPDATE  oxarticles
    SET     oxean = (SELECT oxean FROM oxarticles WHERE oxparentid = oxid),
            oxstock = (SELECT oxstock FROM oxarticles WHERE oxparentid = oxid),
            oxinsert = (SELECT oxinsert FROM oxarticles WHERE oxparentid = oxid)

而父母 oxid 绑定到子/变体的 oxparentid 列。

很遗憾,我收到了错误:

Your can’t specify target table for update in FROM clause

请问我该如何解决?

【问题讨论】:

【参考方案1】:

你可以这样做:

UPDATE oxarticles a 
    LEFT JOIN oxarticles b ON a.oxid=b.oxparentid
SET a.oxean =b.oxean,
    a.oxstock  =b.oxstock ,
    a.oxinsert  =b.oxinsert 

【讨论】:

谢谢。这会导致错误“oxean 不能为空”,因为“oxarticles a LEFT JOIN oxarticles b ON a.oxid = b.oxparentid”也会选择父条目。我认为这是 MySQL 不允许我在同一个表中更新数据的问题。我正在进一步寻找。 @BernhardKraus :我认为这是因为其中一个 oxid 没有父母,并且因为 oxean 不可为空,所以您会收到此异常。您总是可以尝试将左连接更改为连接。但是没有父级的行将不会被更新。但也许这是意料之中的?【参考方案2】:

解决了。这是我的解决方案。

UPDATE  oxarticles a
    SET     a.oxean = ( SELECT oxean FROM ( SELECT oxean, oxparentid, oxartnum FROM oxarticles) tmp WHERE tmp.oxparentid = a.oxid AND tmp.oxartnum LIKE '%GrLos%' LIMIT 0,1),
            a.oxstock = ( SELECT oxstock FROM ( SELECT oxstock, oxparentid, oxartnum FROM oxarticles) tmp WHERE tmp.oxparentid = a.oxid AND tmp.oxartnum LIKE '%GrLos%' LIMIT 0,1),
            a.oxinsert = ( SELECT oxinsert FROM ( SELECT oxinsert, oxparentid, oxartnum FROM oxarticles) tmp WHERE tmp.oxparentid = a.oxid AND tmp.oxartnum LIKE '%GrLos%' LIMIT 0,1),
            a.oxsubclass = ( SELECT oxsubclass FROM ( SELECT oxsubclass, oxparentid, oxartnum FROM oxarticles) tmp WHERE tmp.oxparentid = a.oxid AND tmp.oxartnum LIKE '%GrLos%' LIMIT 0,1),
            a.oxsort = ( SELECT oxsort FROM ( SELECT oxsort, oxparentid, oxartnum FROM oxarticles) tmp WHERE tmp.oxparentid = a.oxid AND tmp.oxartnum LIKE '%GrLos%' LIMIT 0,1),
            a.oxvarname = '',
            a.oxvarstock = 0,
            a.oxvarcount = 0,
            a.oxvarminprice = 0.00,
            a.oxvarmaxprice = 0.00

仅供参考:

 AND tmp.oxartnum LIKE '%GrLos%'

只是标识表数据中的某种数据类型。就我而言,有可能有真正变体的文章。更新过程不能触及这些,所以我只在“oxartnum”列中选择包含字符串“GrLos”的文章。

由于 MySQL 不支持同一个表中的 udate 操作,但您必须强制 MySQL 创建一个临时表。这就是我们对 set 操作中的子选择要做的事情:

SET a.oxean = ( SELECT oxean FROM ( SELECT oxean, oxparentid, oxartnum FROM oxarticles) tmp WHERE tmp.oxparentid = a.oxid AND tmp.oxartnum LIKE '%GrLos%' LIMIT 0,1)

如果一篇文章有​​多个变体,我将子选择结果限制为 1

limit 0,1

也许这可能会在未来对其他人有所帮助。

【讨论】:

以上是关于MySQL 无法在 FROM 子句中指定更新的目标表的主要内容,如果未能解决你的问题,请参考以下文章

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

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

MySQL:您不能在 FROM 子句中指定目标表“任务”进行更新

如何重写此 MySQL 查询,使其不会引发此错误:您无法在 FROM 子句中指定目标表 'crawlLog' 进行更新?

sql mysql错误您无法在FROM子句中指定要更新的目标表

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