УДАЛЕНИЕ СЛИЯНИЕМ только на основе родительского идентификатора

#sql #sql-server #join #sql-merge

#sql #sql-сервер #Присоединиться #sql-слияние

Вопрос:

у меня есть таблица под названием Доступность, которая выглядит следующим образом.

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

теперь ItemId — это связь с таблицей элементов, а LocationID — это связь с таблицей местоположений, для каждого элемента может быть только 1 запись на местоположение.

у меня есть другая таблица, в которой обновлена доступность, но только для некоторых элементов, а не для всех элементов, теперь я хочу выполнить слияние и вставить все, чего не хватает в цели, а также обновить цель, но моя задача заключается в том, что мне делать, когда, допустим, некоторые местоположения из определенных элементов были удалены, я хочу удалить, когда отсутствует источник, доступность ТОЛЬКО для элементов, которые я сейчас сопоставляю,

вот пример. допустим, в исходном коде у меня есть несколько записей для ItemId 2356, теперь я хочу сопоставить их с target только для записей с ItemId = 2356. итак, когда у меня в цели 6 записей для ItemId 2356, а в исходном коде у меня есть только 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
  

но, к сожалению, мое текущее СЛИЯНИЕ удаляет из цели все, что оно не находит в источнике, включая записи, которые имеют другой ItemId.

вот мое СЛИЯНИЕ.

 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; 
  

Комментарии:

1. Это предложение не имеет смысла: «я хочу удалить, когда отсутствует источник, доступность ТОЛЬКО для элементов, которые я сейчас сопоставляю» Как источник может быть одновременно отсутствующим и совпадающим? Вероятно, вам нужно будет привести пример, чтобы было понятно.

2. @TabAlleman я обновил свой вопрос, надеюсь, теперь я более конкретен.

Ответ №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; 
  

Комментарии:

1. спасибо, работает точно так, как ожидалось, теперь делаю отдельный ItemId как я буду обрабатывать производительность, когда в источнике будет около 120 000 записей, а в цели будет 350 000 записей, есть ли лучший способ сделать это? что касается производительности, скорости.

2. Попробуйте поместить некластеризованный индекс в ItemId во временной таблице