为什么此Join-Update查询会更新所有值?

时间:2019-05-22 00:32:22

标签: sql sql-server

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

我在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',其中WEATHER的{​​{1}}是'SUNNY',并且两个表之间进行内部联接,但是列TABLE_B的每个值都是已更新为“快乐”。

在SQL Server中FEEL的含义是什么,何时使用?为什么“内部联接”会更新所有值?

1 个答案:

答案 0 :(得分:3)

此查询:

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_A中与ONWHERE子句中的条件匹配的所有行。但是,这些条件都没有涉及TABLE_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_A中的UPDATE引用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';