【问题标题】:MySQL can’t specify target table for update in FROM clauseMySQL 无法在 FROM 子句中指定更新的目标表
【发布时间】: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

请问我该如何解决?

【问题讨论】:

    标签: mysql subquery


    【解决方案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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      • 2013-01-17
      • 2014-07-19
      • 2020-09-12
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      相关资源
      最近更新 更多