SQL SERVER 2014
我需要使用SourceTable
中的值更新TargetTable中的两列SourceTbl
PersonNr | Block | BlockReason |
---------|----------|---------------|
000001 | 1 | abuse |
000001 | 1 | age |
000001 | 0 | memo |
000002 | 1 | age |
000002 | 0 | |
000003 | 0 | |
000003 | 0 | |
000004 | 1 | behaviour |
000005 | 0 | |
TargetTable
PersonNr | Block | BlockReason |
---------|----------|---------------|
000001 | 0 | |
000001 | 0 | |
000002 | 0 | |
000002 | 0 | |
000004 | 1 | |
000005 | 0 | |
需要的结果:
PersonNr | Block | BlockReason |
---------|----------|---------------|
000001 | 1 | abuse |
000001 | 1 | abuse |
000002 | 1 | age |
000002 | 1 | age |
000004 | 1 | behaviour |
000005 | 0 | |
{1}}人1得到的是无关紧要的,
至于BlockReason
=' 1'中的一行。
我尝试过这个非常直接的更新:
Block
但结果是错误的结果行,其中Block和Reason分别更新:
UPDATE
src
SET
src.Block = '1',
src.BlockReason = targ.BlockReason
FROM
SourceTbl src
INNER JOIN
TargetTable targ
ON
src.PersonNr= targ.PersonNr
WHERE src.Block = '1'
接下来我尝试过:
PersonNr | Block | BlockReason |
---------|----------|---------------|
000001 | 1 | memo |
得到错误
MERGE INTO TargetTable AS TGT
USING
(
SELECT Block, BlockReason, PersonNr
FROM SourceTbl
GROUP BY Block, BlockReason, PersonNr
) AS SRC
ON
SRC.PersonNr= TGT.PersonNr AND
SRC.Block= '1'
WHEN MATCHED THEN
UPDATE SET TGT.Block= SRC.Block, TGT.BlockReason= SRC.BlockReason;
有任何帮助吗?非常感谢!真正做到。完全。
答案 0 :(得分:1)
您的查询的问题在于它提供了重复值,并且它尝试多次更新同一条记录。由于您没有使用任何聚合函数,因此子查询中的GROUP BY
没有任何意义
我们取一个id(比如1)并检查你的查询出了什么问题。
src.PersonNr | src.Block | src.BlockReason | tgt.PersonNr | tgt.Block | tgt.BlockReason |
-------------|--------------|-------------------|--------------
000001 | 1 | abuse | 000001 | 0 | |
000001 | 1 | age | 000001 | 0 | |
000001 | 1 | abuse | 000001 | 0 | |
000001 | 1 | age | 000001 | 0 | |
您的查询会为您提供上述结果,并尝试针对每条记录更新目标表2次,包括滥用行为和下次年龄。
您可以尝试以下查询:
MERGE INTO TargetTable AS TGT
USING
(
SELECT Block, BlockReason, PersonNr
FROM(
SELECT Block, BlockReason, PersonNr,ROW_NUMBER() OVER (PARTITION BY PersonNr ORDER BY [YourPrimaryKey]) RN
FROM SourceTbl ) X
WHERE X.RN=1
) AS SRC
ON
SRC.PersonNr= TGT.PersonNr AND
SRC.Block= '1'
WHEN MATCHED THEN
UPDATE SET TGT.Block= SRC.Block, TGT.BlockReason= SRC.BlockReason;
答案 1 :(得分:0)
您的数据中有重复项。将另一个(或多个)列添加到ON
的{{1}}子句中,该子句将有助于确定一个记录,或者在合并之前找到删除重复项的方法。
答案 2 :(得分:0)
UPDATE
应该是这样的:
UPDATE
targ
SET
Block = '1',
BlockReason = src.BlockReason
FROM
SourceTbl src
INNER JOIN
TargetTable targ
ON
src.PersonNr= targ.PersonNr
WHERE src.Block = '1'
由于我们仅使用SourceTbl
Block
为1
的行,因此受此更新影响的行不应该结束我的理由Block
为0
。
如果SourceTbl
中的多行连接到TargetTbl
中的一行,但仍然存在一般性问题,这是不确定的,但是因为您已指出不需要确定性在这里,它不应该导致问题。