首页 > 解决方案 > 为什么这个 Join-Update 查询会更新所有值?

问题描述

我犯了一些错误,一列的所有值都被更新了。

我在 SQL Server 2008 R2 中做到了这一点。

我应该运行一些这样的查询:

UPDATE TABLE_A
SET FEEL = 'HAPPY'
FROM TABLE_A A 
INNER JOIN TABLE_B B ON A.SN = B.SN
WHERE B.WEATHER = 'SUNNY';

但是,我犯了一个错误并运行了这个:

UPDATE TABLE_A
SET FEEL = 'HAPPY'
FROM TABLE_C A 
INNER JOIN TABLE_B B ON A.SN = B.SN
WHERE B.WEATHER = 'SUNNY';

甚至TABLE_C有一列[SN].

我希望此查询将 TABLE_A 的 FEEL 更新为“HAPPY”,其中WEATHERTABLE_B“SUNNY”是两个表之间的内部连接,但列的每个值FEEL都更新为“HAPPY”。

在 SQL Server 中意味着什么Update A set ~ from c以及应该在什么时候使用它?为什么“内部连接”会更新所有值?

标签: sqlsql-server

解决方案


这个查询:

UPDATE TABLE_A
     SET FEEL = 'HAPPY'
     FROM TABLE_C A INNER JOIN
          TABLE_B B
          ON A.SN = B.SN
    WHERE B.WEATHER = 'SUNNY';

是说更新与and子句TABLE_A中的条件匹配的所有行。但是,这些条件都不涉及. 因此,没有任何内容被过滤。实际上,您所做的相当于:ONWHERETABLE_A

UPDATE AA
     SET FEEL = 'HAPPY'
     FROM TABLE AA CROSS JOIN
          TABLE_C A INNER JOIN
          TABLE_B B
          ON A.SN = B.SN
    WHERE B.WEATHER = 'SUNNY';

这在UPDATE.

当你这样做时:

UPDATE TABLE_A
    SET FEEL = 'HAPPY'
    FROM TABLE_A A INNER JOIN
         TABLE_B B
         ON A.SN = B.SN
     WHERE B.WEATHER = 'SUNNY';

SQL Server 对别名总是替换表引用的规则做了一个例外。它仍然允许TABLE_AUPDATE参考A。所以,没有CROSS JOIN.

就我个人而言,我认为这是一种损坏,因为表别名应始终替换表引用。微软的开发人员不这么认为。并且没有指导这种语法的标准。

如果您有FROM子句,我建议始终使用表别名。

UPDATE A
    SET FEEL = 'HAPPY'
    FROM TABLE_A A INNER JOIN
         TABLE_B B
         ON A.SN = B.SN
     WHERE B.WEATHER = 'SUNNY';

推荐阅读