Sql 插入目标表中不存在的记录,并使用“合并”删除源数据集中不存在的记录
我有一个数据如下表1的表格 我还有另一个数据集,如下面的数据集 现在我需要插入表1中不存在的记录,您可以看到该记录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
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