Как объединить две таблицы без первичного ключа (или как удалить остатки от слияния)? - PullRequest
1 голос
/ 02 сентября 2011

Скажем, у меня есть две таблицы:

     Table A                             Table B  
_______________________            _______________________
 Id | Description                    Id | Description
-----------------------            -----------------------
 1  | Some Val                       1  | Some Val                      
 2  | More Data                      2  | More Data
 2  | Even More                      2  | Less Is More
 2  | More again                     3  | This Changed
 3  | Other Values                   4  | these are random             
 3  | But Not this                 ------------------------  
 4  | these are random             
-----------------------

Как я могу выполнить слияние с таблицей A изменений таблицы B и получить это:

     Table A                       
_______________________            
 Id | Description                  
-----------------------            
 1  | Some Val                     
 2  | More Data                      
 2  | Less Is More
 3  | This Changed
 4  | these are random             
-----------------------

Когда я пытаюсь что-то вроде этого:

merge TableA as target
using (select Id, Description
       from   TableB) 
       as source (Id, Description)
on (target.Id = source.Id)             
when MATCHED then
    update set Id = source.Id, Description = source.Description
when NOT MATCHED then
    insert (Id, Description)
    values (source.Id, source.Description);

Я получаю эту ошибку:

Оператор MERGE пытался ОБНОВИТЬ или УДАЛИТЬ одну и ту же строку более одного раза. Это происходит, когда целевая строка соответствует более чем одной исходной строке. Оператор MERGE не может ОБНОВИТЬ / УДАЛИТЬ одну и ту же строку целевой таблицы несколько раз. Уточните предложение ON, чтобы убедиться, что целевая строка совпадает не более чем с одной исходной строкой, или используйте предложение GROUP BY для группировки исходных строк.

Это потому, что Id не уникален. Я могу добавить описание, но тогда оно никогда не обновится. Это означает, что изменения потеряют строки.

Что мне действительно нужно, так это способ сказать: оставьте то, что соответствует, вставьте то, что отсутствует, и удалите остальное.

Как я могу удалить эту часть?

ПРИМЕЧАНИЕ: Я понял, что таблица A действительно просто принимает все значения таблицы B. Но я все еще хочу объединить, потому что на практике между этими таблицами будет мало что меняться. Полное усечение и повторная вставка излишни.

Ответы [ 2 ]

1 голос
/ 13 декабря 2014
merge TableA as target 
using (select * from   TableB) as source 
on ( target.id = source.id AND target.description = source.description )             
--when MATCHED then
    --update set id = source.id, description = source.description
when NOT MATCHED then
    insert (id, description)
    values (source.id, source.description)
when NOT MATCHED BY source then DELETE; 
0 голосов
/ 02 сентября 2011

Должен был искать немного дольше.Требуется опция NOT MATCH ON SOURCE:

merge TableA as target
using (select Id, Description
       from   TableB) 
       as source (Id, Description)
on (target.Id = source.Id)             
when NOT MATCHED BY SOURCE then DELETE    
when NOT MATCHED then
    insert (Id, Description)
    values (source.Id, source.Description);   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...