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' 进行更新?