MERGE DELETE 仅基于父 id

MERGE DELETE only based on parent id

我有一个名为 Availability 的 table,看起来像这样。

| Id | Allocated | AverageCost | Demand | InStock | SourceDate | LocationId | ItemId

现在 ItemId 与 Items table 有关系,LocationId 与 Location table 有关系,每个项目的每个位置只能有 1 条记录。

我有另一个 table 正在更新可用性,但仅针对某些项目,而不是所有项目,现在我想进行合并并插入目标中缺少的所有项目,并同时更新目标,但我面临的挑战是当假设特定项目的某些位置已被删除时我要做什么,我想在源缺少可用性时删除我现在正在匹配的项目,

这是一个例子。假设在源代码中我有多个 ItemId 2356 的记录,现在我只想将它们与具有 itemId = 2356 的记录的目标匹配。所以当我在目标中有 ItemId 2356 的 6 条记录并且在源代码中我只有 4 条记录对于这个 ItemId,我希望它应该从目标中删除源中缺少的 2 条记录。

目标

ID  A   AC     D   IS    Date      LocationId    ItemID
1 | 0 | 2.36 | 23 | 56 | 3/23/18 | 5689       | 2356 
2 | 0 | 5.36 | 10 | 34 | 3/23/18 | 5634       | 2356 
3 | 0 | 5.36 | 10 | 34 | 3/23/18 | 5756       | 1497
4 | 0 | 5.36 | 10 | 34 | 3/23/18 | 5371       | 2356 
5 | 0 | 5.36 | 10 | 34 | 3/23/18 | 2873       | 2356
6 | 0 | 5.36 | 10 | 34 | 3/23/18 | 8549       | 2356
7 | 0 | 5.36 | 10 | 34 | 3/23/18 | 8549       | 3585
8 | 0 | 5.36 | 10 | 34 | 3/23/18 | 8549       | 2943
9 | 0 | 5.36 | 10 | 34 | 3/23/18 | 2958       | 2356

来源

 A   AC     D   IS    Date      LocationId    ItemID
 0 | 2.36 | 23 | 56 | 3/23/18 | 5689       | 2356 
 0 | 5.36 | 10 | 34 | 3/23/18 | 5634       | 2356 
 0 | 5.36 | 10 | 34 | 3/23/18 | 2873       | 2356
 0 | 5.36 | 10 | 34 | 3/23/18 | 8549       | 2356

但不幸的是,我当前的 MERGE 正在从目标中删除它在源中找不到的所有内容,包括具有不同 ItemId 的记录。

这是我的 MERGE。

MERGE Availability AS target
USING #tmpAvailability AS SOURCE 
ON target.[locationId] = SOURCE.[locationId]
  AND target.[ItemId] = Source.[ItemId]   


WHEN MATCHED THEN 

UPDATE SET TARGET.[Allocated] = source.[Allocated],  
           TARGET.[AverageCost] =  source.[AverageCost],
           TARGET.[Demand] =  source.[Demand],
           TARGET.[InStock] =  source.[InStock],
           TARGET.[SourceDate] =  source.[SourceDate]


WHEN NOT MATCHED BY TARGET THEN  

INSERT ([Allocated],[AverageCost],[Demand],[InStock],[SourceDate],[LocationId],[ItemId])          
VALUES (SOURCE.[Allocated] ,SOURCE.[AverageCost],source.[Demand],source.[InStock],source.[SourceDate],source.[LocationId],source.[ItemId])


when Not Matched By Source and source.[ItemId] is not null then
DELETE; 

请试试这个:

;WITH MergeTable AS (
    SELECT a.[Allocated],a.[AverageCost],a.[Demand],a.[InStock],a.[SourceDate],a.[LocationId],a.[ItemId]
    FROM Availability a
    WHERE a.ItemID IN (SELECT DISTINCT ItemID FROM #tmpAvailability)
)
MERGE MergeTable AS target
USING #tmpAvailability AS SOURCE 
    ON target.[locationId] = SOURCE.[locationId]
        AND target.[ItemId] = Source.[ItemId]   
WHEN MATCHED THEN 
UPDATE SET TARGET.[Allocated] = source.[Allocated],  
           TARGET.[AverageCost] =  source.[AverageCost],
           TARGET.[Demand] =  source.[Demand],
           TARGET.[InStock] =  source.[InStock],
           TARGET.[SourceDate] =  source.[SourceDate]

WHEN NOT MATCHED BY TARGET THEN  
INSERT ([Allocated],[AverageCost],[Demand],[InStock],[SourceDate],[LocationId],[ItemId])          
VALUES (SOURCE.[Allocated] ,SOURCE.[AverageCost],source.[Demand],source.[InStock],source.[SourceDate],source.[LocationId],source.[ItemId])

WHEN NOT MATCHED BY SOURCE AND source.[ItemId] IS NOT NULL THEN
DELETE;