我有什么:
两张表A和B.
A: Col1 Col2 Col3 Col1_Transformed Col2_Transformed
B: Col1 Col2 Col3
除了一些修改过的数据之外,它们具有完全相同的列,它们都没有主键,唯一字段或其他(我需要处理的极端情况)。
表A仅包含表B中的部分数据。 可以说,我批量读取表B中的10000行,然后修改数据并将其写入表A(* _Transform列)。
我需要什么:
我需要使用表A中的数据更新表B. 拥有主键或某些标识列很容易:
UPDATE target
SET target.Col1 = source.__Col1
FROM B target
join A as source
ON target.Id = source.Id
但我没有。
接下来的自然猜测是继续使用Col1 Col2 Col3形成的自然键。
UPDATE target
SET target.Col1 = source.__Col1
FROM B target
join A as source
ON target.Col1 = source.Col1 AND
target.Col2 = source.Col2 AND
target.Col3 = source.Col3
这个东西不起作用,原因是可能的NULL值比较。如果target.Col1或source.Col1为NULL,则从更新中省略整个记录。
猜#3(使用行号):
我想将row_number添加到表A,它将是我的密钥。
答:row_numb Col1 Col2 Col3 Col1_Transformed Col2_Transformed
而不仅仅是加入表B:
UPDATE target
SET target.Col1 = source.__Col1
FROM B target
join A as source
ON ROW_NUMBER() OVER(ORDER BY target.Col1,target.Col2,target.Col3) = source.ROW_NUMB
Bur row_nubmer不能在join子句中使用。
任何想法怎么做?
答案 0 :(得分:1)
好像你希望NULL
匹配联接,你可以这样做:
UPDATE target
SET target.Col1 = source.__Col1
FROM B target
join A as source
ON (target.Col1 = source.Col1 OR (target.Col1 IS NULL AND source.Col1 IS NULL)) AND -- most reliable way to do it
ISNULL(target.Col2,'-1') = ISNULL(source.Col2,'-1') AND -- less reliable but more concise, replace -1 by any data that cannot be in the tables
(target.Col3 = source.Col3 OR (target.Col3 IS NULL AND source.Col3 IS NULL))
答案 1 :(得分:0)
使用ISNULL
UPDATE target
SET target.Col1 = source.__Col1
FROM B target
join A as source
ON IsNull(target.Col1,'') = IsNUll(source.Col1,'')
AND IsNull(target.Col2,'') = IsNull(source.Col2,'')
AND IsNull(target.Col3,'') = IsNull(source.Col3,'')
CTE
示例:
;With CTETableA
AS
(
Select Col1,Col2,Col3,Col1_Transformed,Col2_Transformed
ROW_NUMBER() OVER(ORDER BY Col1,Col2,Col3) id
from A
),
CTETableB
As
(
Select Col1,Col2,Col3,ROW_NUMBER() OVER(ORDER BY Col1,Col2,Col3) id
from B
)
UPDATE target
SET target.Col1 = source.Col1
FROM CTETableB target
join CTETableA as source
ON target.Id = source.Id
Insert into B(Col1)
Select Col1 from CTETableB