#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 во временной таблице