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