【问题标题】:MERGE DELETE only based on parent idMERGE DELETE 仅基于父 id
【发布时间】:2019-03-20 19:12:05
【问题描述】:

我有一个名为“可用性”的表,看起来像这样。

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

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

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

这是一个例子。假设在源中我有多个 ItemId 2356 的记录,现在我只想将它们与 target 匹配 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; 

【问题讨论】:

  • 这句话没有意义:“我想在源丢失时删除仅适用于我现在匹配的项目的可用性”源如何既丢失又匹配?你可能需要举一个例子来说明清楚。
  • @TabAlleman 我更新了我的问题,我希望现在我更具体。

标签: sql sql-server join sql-merge


【解决方案1】:

请试试这个:

;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; 

【讨论】:

  • 谢谢,完全按预期工作,现在执行不同的 ItemId 当源将有 120,000 条记录而目标将有 350,000 条记录时,我将如何处理性能,是否有更好的方法来解决这个问题?在性能、速度方面。
  • 尝试在临时表的ItemId上放置非聚集索引
猜你喜欢
  • 1970-01-01
  • 2012-08-06
  • 2021-05-27
  • 1970-01-01
  • 2013-08-03
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多