使用来自另一个表的值更新表中的列并获取意外的NULL值

时间:2018-12-17 23:38:00

标签: sql sql-server tsql

我正在使用多个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值有过任何经验,那么我会非常感激任何解决问题的技巧,因为我不太确定从哪里开始寻找。

2 个答案:

答案 0 :(得分:0)

要进行故障排除(并永久停止使用UPDATE…FROM),请添加另一个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
    ), C as
    (
      select a.Name a_name, b.Name b_name, a.ID a_id, b.ID b_id
      FROM A
      LEFT JOIN B
      ON A.code = B.code
    )
    select * from c
    --update C set a_name = b_name, a_id = b_id

检查结果,排除故障,然后切换到UPDATE。

答案 1 :(得分:0)

您正在执行从A到B的左联接。这种左联接意味着,如果表A行没有匹配的B行,那么B中的所有值都将为null。几乎可以肯定,这是您的空值来自何处。

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

如果没有B行,则需要将一些默认值放到A中,那么您仍然需要进行左连接,但是将set命令更改为

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

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

相关问题