Sql 插入目标表中不存在的记录,并使用“合并”删除源数据集中不存在的记录

Sql 插入目标表中不存在的记录,并使用“合并”删除源数据集中不存在的记录,sql,sql-server,sql-server-2008,merge,Sql,Sql Server,Sql Server 2008,Merge,我有一个数据如下表1的表格 我还有另一个数据集,如下面的数据集 现在我需要插入表1中不存在的记录,您可以看到该记录 id valueId Value ----------- ----------- ------- 1 1 Value 4 不在表1中,则该记录应插入并需要从表1中删除不在 id valueId Value ----------- ----------- ------- 1

我有一个数据如下表1的表格

我还有另一个数据集,如下面的数据集

现在我需要插入表1中不存在的记录,您可以看到该记录

id          valueId     Value
----------- ----------- -------
1           1           Value 4
不在表1中,则该记录应插入并需要从表1中删除不在

id          valueId     Value
----------- ----------- -------
1           1           Value 3
,但在不影响其他记录的情况下,其他记录指id=1且valueId=2的记录

我使用了我使用MERGE编写的以下T-SQL,它插入丢失的记录,但删除数据集中不存在的所有记录

预期结果:

更新:


当源不匹配且不存在时,可以执行此操作。从cte中选择*,其中cte.[Value]=TV.[Value],但最好只使用两个语句。@SAM:更新的问题中有一个错误。更新和删除行刚刚被交换。是的,谢谢@RaviSingh@SAM:为什么最后一行1,2,N'Value 3'不符合删除条件?@RaviSingh不符合条件,因为ValueId不同。很抱歉,我认为我的问题出了错。我会编辑的。我不仅考虑了值列,我还考虑了所有的列。那么您自己的查询是正确的,因为行1,1,N'Value 3',1,2,N'Value 1',1,2,N'Value 2',1,2,N'Value 3'不匹配,应该删除。我们必须使用两个语句是吗?嗯。。我想在一个MERGE语句中完成它。如果我们使用两个语句,我们不需要合并,我们可以使用一个简单的JOIN语句
id          valueId     Value
----------- ----------- -------
1           1           Value 4
id          valueId     Value
----------- ----------- -------
1           1           Value 3
DECLARE @tmp_value AS TABLE
    (
      id INT ,
      valueId INT ,
      [Value] NVARCHAR(50)
    ) ;
INSERT  @tmp_value
        ( [id], [valueId], [Value] )
VALUES  ( 1, 1, N'Value 1' ),
        ( 1, 1, N'Value 2' ),
        ( 1, 1, N'Value 3' ),
        ( 1, 2, N'Value 1' ),
        ( 1, 2, N'Value 2' ),
        ( 1, 2, N'Value 3' ) ;

--SELECT  *
--FROM    @tmp_value AS TV ;
WITH    cte
          AS ( SELECT   1 AS id , 1 AS valueId , 'Value 1' AS [Value]
               UNION
               SELECT   1 AS id , 1 AS valueId , 'Value 2' AS [Value]
               UNION
               SELECT   1 AS id , 1 AS valueId , 'Value 4' AS [Value]
             )
    MERGE @tmp_value AS TV
        USING cte
        ON [cte].[id] = [TV].[id]
            AND [cte].[valueId] = [TV].[valueId]
            AND [cte].[Value] = [TV].[Value]
        WHEN NOT MATCHED 
            THEN INSERT VALUES   ( id , [valueId] , [Value] )
        WHEN NOT MATCHED BY SOURCE 
            THEN DELETE ;

SELECT  *
FROM    @tmp_value
id          valueId     Value
----------- ----------- --------------------------------------------------
1           1           Value 1
1           1           Value 2
1           1           Value 4
1           2           Value 1
1           2           Value 2
1           2           Value 3
DECLARE @tmp_value AS TABLE
    (
      id INT ,
      valueId INT ,
      [Value] NVARCHAR(50)
    ) ;
INSERT  @tmp_value
        ( [id], [valueId], [Value] )
VALUES  ( 1, 1, N'Value 1' ),
        ( 1, 1, N'Value 2' ),
        ( 1, 1, N'Value 3' ),
        ( 1, 2, N'Value 1' ),
        ( 1, 2, N'Value 2' ),
        ( 1, 2, N'Value 3' ) ;

--SELECT  *
--FROM    @tmp_value AS TV ;
WITH    cte
          AS ( SELECT   1 AS id , 1 AS valueId , 'Value 1' AS [Value]
               UNION
               SELECT   1 AS id , 1 AS valueId , 'Value 2' AS [Value]
               UNION
               SELECT   1 AS id , 1 AS valueId , 'Value 4' AS [Value]
              )
    MERGE @tmp_value AS TV
        USING cte
        ON [cte].[id] = [TV].[id]
            AND [cte].[valueId] = [TV].[valueId]
            AND [cte].[Value] = [TV].[Value]
        WHEN NOT MATCHED 
            THEN INSERT VALUES   ( id , [valueId] , [Value] )
        ;


WITH    cte
          AS ( SELECT   1 AS id , 1 AS valueId , 'Value 1' AS [Value]
               UNION
               SELECT   1 AS id , 1 AS valueId , 'Value 2' AS [Value]
               UNION
               SELECT   1 AS id , 1 AS valueId , 'Value 4' AS [Value]
             )
    MERGE @tmp_value AS TV
        USING cte
        ON ([cte].[id] = [TV].[id]
            AND [cte].[valueId] = [TV].[valueId]
           AND [cte].[Value] = [TV].[Value])
            or not( [TV].[id] in (select distinct id from cte)
            and [TV].[valueId] in (select distinct valueid from cte))
        WHEN NOT MATCHED 
            THEN INSERT VALUES   ( id , [valueId] , [Value] )
        WHEN NOT MATCHED BY Source 
            THEN DELETE ;

SELECT  *
FROM    @tmp_value