Can I apply a WHERE clause on the target in a MERGE statement?
我有一个目标表,其中包含带有
- ,如果该行存在于源和目标中,则该行应具有
IsActive true - ,如果仅存在于源中,则应新建一个行插入到目标中,并且
IsActive true - 如果它仅存在于目标中,则应将
IsActive 设置为false。
除了目标以外,其他非常简单表还具有与源表相关的区分列
(我的规范化表包含来自多个系统的相同数据类型的行-我从这些系统中检索数据
这是一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | IF OBJECT_ID('tempdb..#target') IS NOT NULL DROP TABLE #target IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source CREATE TABLE #target ( Id INT, SourceId INT, IsActive BIT ) INSERT #target VALUES (1, 1, 0) INSERT #target VALUES (2, 1, 1) INSERT #target VALUES (3, 2, 1) CREATE TABLE #source ( Id INT ) INSERT #source VALUES (1) INSERT #source VALUES (4) DECLARE @SourceId INT = 1; SELECT * FROM #target MERGE INTO #target t USING ( SELECT [Id] FROM #source ) AS s ON t.[Id] = s.[Id] AND t.[SourceId] = @SourceId WHEN MATCHED THEN UPDATE SET [IsActive] = 1 WHEN NOT MATCHED BY TARGET THEN INSERT VALUES ([Id], @SourceId, 1) WHEN NOT MATCHED BY SOURCE THEN UPDATE SET [IsActive] = 0; SELECT * FROM #target |
我最初的尝试是在合并条件中包含
最终结果是,无论何时为源系统运行该过程,
到目前为止,我的解决方案是仅对
1 2 3 4 | UPDATE #target SET [IsEnabled] = 0 WHERE [SourceId] = @SourceId AND [ID] NOT IN (SELECT [ID] FROM #source) |
是否可以在
因此您的结果集应为
1 2 3 4 | 1 1 1 2 1 0 3 2 1 4 1 1 |
,在这种情况下,您的合并语句应为
1 2 3 4 5 6 | merge #target as t using #source as source on (t.id=source.id) when matched then update set isactive=1 when not matched by target then insert values (id, @sourceid,1) when not matched by source and SourceID=@sourceID then update set isactive=0 |
完整测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | CREATE TABLE #target ( Id INT, SourceId INT, IsActive BIT ) INSERT #target VALUES (1, 1, 0) INSERT #target VALUES (2, 1, 1) INSERT #target VALUES (3, 2, 1) CREATE TABLE #source ( Id INT ) INSERT #source VALUES (1) INSERT #source VALUES (4) DECLARE @SourceId INT select @SourceId = 1; merge #target as t using #source as source on (t.id=source.id) when matched then update set isactive=1 when not matched by target then insert values (id, @sourceid,1) when not matched by source and SourceID=@SourceID then update set isactive=0; SELECT * FROM #target drop table #target; drop table #source |
结果。 。
1 2 3 4 5 6 | Id SourceId IsActive ----------- ----------- -------- 1 1 1 2 1 0 3 2 1 4 1 1 |