我有两个要合并的表,一个是 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
语句解决此问题?
答案 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
子句