SQL Server合并目标上不匹配的多个插入

时间:2019-05-27 19:29:36

标签: sql sql-server tsql

我有两个要合并的表,一个是 source ,另一个是 target 来源中的数据是 CTE 的输出。

我正在尝试将数据插入到Target中,但是我有两个条件可以将数据插入到Target表中。

我正在使用“合并”来更新现有数据并插入新行。目标表包含历史数据。

Source中的状态将为1或2,Target中的状态将为R或S。

这是我需要执行的过程的示例。

下面是源表和目标表中的数据,也很少需要检查的条件。

来源

| ID    |Name | Cond| Status |            
+-------+-----+-----+--------+
|   1   | A   | XYZ | 1      |

目标

| ID    |Name | Cond| Status |  cdate          
+-------+-----+-----+--------+
|   1   | A   | XYZ | R      | 4/09/2019 4:34:28

条件1:现在如果源数据有一些更改,则source.status = 2,如果target.id = source.id和target.status ='R',则目标需要用源数据更新。

来源

    | ID    |Name | Cond| Status |            
    +-------+-----+-----+--------+
    |   1   | B   | MNO | 2      |

目标

    | ID    |Name | Cond| Status |   cdate         
    +-------+-----+-----+--------+
    |   1   | B   | MNO | R      | 4/09/2019 4:34:28

条件2:执行一个存储过程后,target.status更改为'S'。

现在,如果target.status = 'S'source.status = 2(target.name != source.name or target.cond != source.cond),则需要以target.status为'R'的行插入目标。

来源

    | ID    |Name | Cond| Status |            
    +-------+-----+-----+--------+
    |   1   | B   | MNO | 2      |

目标

    | ID    |Name | Cond| Status |            
    +-------+-----+-----+--------+
    |   1   | A   | XYZ | S      | 4/09/2019 4:34:28
    |   1   | B   | MNO | R      | 6/09/2019 7:34:28

要获得结果,我使用了MERGE,如下所示:

MERGE table_1 AS TARGET
USING data_from_cte AS SOURCE ON (TARGET.ID = SOURCE.ID AND Target.status = 'R') 

--WHEN RECORDS ARE MATCHED, UPDATE THE RECORDS IF THERE IS ANY CHANGE
WHEN MATCHED AND TARGET.STATUS = 'R' 
    THEN UPDATE 
             SET TARGET.name = SOURCE.name,
                 TARGET.cond = SOURCE.cond,

--WHEN NO RECORDS ARE MATCHED, INSERT THE INCOMING RECORDS FROM SOURCE TABLE TO TARGET TABLE
WHEN MATCHED AND TARGET.STATUS = 'S' AND source.status = 2 
             AND (target.name != source.name OR target.cond != source.cond)
    THEN INSERT (id, name, cond, status) 
         VALUES (SOURCE.ID, SOURCE.name, SOURCE.cond, 'R')

WHEN NOT MATCHED BY TARGET 
    THEN INSERT (id, name, cond, status) 
         VALUES (SOURCE.ID, SOURCE.name, SOURCE.cond, 'R');

这里的问题是:我无法在WHEN MATCHED语句的MERGE条件下比较目标列和源列。

如何使用MERGE语句或IF ... ELSE语句解决此问题?

1 个答案:

答案 0 :(得分:1)

您似乎很靠近那里。您有点困惑,因为您需要使用exists检查S行的existense,并尝试通过合并语法来做到这一点。无法做到这一点:您只能在INSERT上使用WHEN NOT MATCHED BY TARGET。试试这个:

;MERGE table_1 AS TARGET
USING data_from_cte AS SOURCE -- (add WHERE source.status = 2 to your CTE)
ON (TARGET.ID = SOURCE.ID AND Target.status = 'R') 

--WHEN RECORDS ARE MATCHED, UPDATE THE RECORDS IF THERE IS ANY CHANGE
WHEN MATCHED AND TARGET.STATUS = 'R' AND operation='update' 
    THEN UPDATE 
             SET TARGET.name = SOURCE.name,
                 TARGET.cond = SOURCE.cond,

--WHEN NO RECORDS ARE MATCHED AND NO SAME S ROW EXISTS, INSERT THE INCOMING RECORDS FROM SOURCE TABLE TO TARGET TABLE
WHEN NOT MATCHED AND not exists(select 1 from table_1 t1 where t1.ID = SOURCE.ID AND t1.status = 'S' and t1.name = source.name and t1.cond = source.cond)
    THEN INSERT (id, name, cond, status) 
         VALUES (SOURCE.ID, SOURCE.name, SOURCE.cond, 'R')

第二个(WHEN NOT MATCHED ...)条件已更改,但不要忘记在CTE中添加一个WHERE source.status = 2子句