首页 > 解决方案 > 使用另一个表中的值更新表中的列并获得意外的 NULL 值

问题描述

我正在使用多个 CTE 运行大量更新查询,以使用表“B”中的列的值更新表“A”中的许多列(50+)。查询完成后,表 A 中的所有列都已成功更新,除了包含大量 NULL 值的两列(我会说 75% 的 NULL 值)。这是完全出乎意料的,因为表 A 或表 B 中的两列都不包含任何 NULL 值

简化的示例代码(仅显示最终的 CTE 以及有问题的两列):

    WITH B AS
    (SELECT T.position
     ,CASE WHEN CTE1.full_name = '' THEN CTE2._name 
     ELSE CTE1.full_name 
     END AS Name
     ,CASE WHEN CTE1.emp_id = '' THEN CTE2.emp_id 
     ELSE CTE1.emp_id 
     END AS Id
     FROM T
     LEFT JOIN CTE1
     ON T.code = CTE1.code
     LEFT JOIN CTE2
     ON T.code = CTE2.code
    )

    UPDATE A
    SET A.Name = B.Name, A.Id = B.Id
    FROM A
    LEFT JOIN B
    ON A.code = B.code

这个问题是在黑暗中拍摄的,因为我知道这个简化的代码可能太笼统而无法得出任何结论。如果有人在上述情况下确实有任何意外 NULL 值的经验,任何故障排除提示将不胜感激,因为我不完全确定从哪里开始寻找。

标签: sqlsql-servertsql

解决方案


您正在执行从 A 到 B 的左连接。左连接意味着如果表 A 行没有匹配的 B 行,则 B 中的所有值都将为空。这几乎肯定是您的空值的来源。

您可以进行内部联接,以便仅更新表 A 中具有匹配 B 行的行。这将阻止您获取空值,但可能不是您需要的 - 某些表 A 行根本不会更新。

如果您需要在没有 B 行的情况下将一些默认值放入 A 中,那么您仍然需要进行左连接,但将您的 set 命令更改为类似

SET A.Name = COALESCE(B.Name, "defaultvalue")

如果您认为每个 Table A 行都应该有一个匹配的行,那么您需要调试您的 CTE 并找出哪个没有返回您期望的值。


推荐阅读