带有 INNER JOIN 的 UPDATE 未更新

Posted

技术标签:

【中文标题】带有 INNER JOIN 的 UPDATE 未更新【英文标题】:UPDATE with INNER JOIN is not updating 【发布时间】:2018-08-31 18:16:17 【问题描述】:

我正在尝试将影响值从旧表 (esp) 转移到新表 (esm)。两个表共享相似的结构:

esp
+--------+------+----------------------------
|codeNorm|impact|Other columns i dont care...
+--------+------+----------------------------

esm
+--------------+------+--------------------------------------
|codeMasterNorm|impact|Other different columns i dont care...
+--------------+------+--------------------------------------

首先我创建了一个 SELECT 查询,它只带来它们之间有不同影响的记录(影响可以是 NULL):

SELECT esm.codeMasterNorm, esm.impact, esp.codeNorm, esp.impact FROM esm
INNER JOIN esp ON esp.codeNorm = esm.codeMasterNorm AND IFNULL(esp.impact, 0) <> IFNULL(esm.impact, 0);

返回:

163 行(0.75 秒)

然后我创建了 UPDATE/INNER JOIN 查询

UPDATE esm
INNER JOIN esp ON esp.codeNorm = esm.codeMasterNorm AND IFNULL(esp.impact, 0) <> IFNULL(esm.impact, 0)
SET esm.impact = esp.impact;

返回:

查询正常,163 行受影响(1.35 秒)匹配行:163 更改:163 警告:0

但是当我再次重新运行 SELECT 查询时,这会返回相同的结果:

163 行(1.25 秒)

关于为什么不更新记录的任何想法?

【问题讨论】:

我无法复制这个结果。 esp.codeNormesm.codeMasterNorm 是 1:1 吗?如果每个esm 记录有两个esp 记录(基于该字段比较),并且esp 行具有不同的impact 值,那么您不能(显然)给esm 记录这两个值。检查SELECT codeNorm FROM esp GROUP BY codeNorm HAVING COUNT(*) &lt;&gt; 1;它会给你一个重复的 codeNorm 值的列表。 @Uueerdo 是的,这就是问题所在。有人重新插入了一些值并删除了表中的 de UNIQUE 索引。您可以添加答案以便我将其标记为有效并关闭问题吗? :) 【参考方案1】:

执行 UPDATE JOIN 查询时;如果连接不是 1:1,则分配值的来源未定义。

在这种特殊情况下,虽然由于 a.x != b.x 条件,连接在技术上是 1:1,但更新创建了不同的连接对。没有那个条件就假设的 1:1 是不正确的。

【讨论】:

以上是关于带有 INNER JOIN 的 UPDATE 未更新的主要内容,如果未能解决你的问题,请参考以下文章

Mysql update inner join

ORACLE SQL UPDATE 与 INNER JOIN 不起作用

Sql Server 与 MySql 在使用 update inner join 时的区别

使用基于另一个填充表的INNER JOIN UPDATE语句更新空表

update inner join set 和 update set from ,如何使用一个表中的字段更新另一个表中字段,MySQL和SqlServer不一样

在 SELECT ... INNER JOIN ... FOR UPDATE 的情况下,字符串的顺序是啥锁定以及如何避免死锁?