2012-02-22 4 views
5

Я хочу, чтобы создать объединение, которое сравнить две таблицы и вставки не совпавшие значений в другую третью таблицу или таблицы переменной что-то вроде этого:SQL Слияния с вставки в другую таблицу

MERGE Assets AS target 
USING (@id, @name)FROM Sales AS source (id, name) ON (target.id = SOURCE.id) 
WHEN MATCHED THEN 
    UPDATE SET target.Status = @status, target.DateModified = SYSUTCDATETIME() 
WHEN NOT MATCHED THEN 
    INSERT INTO @tableVar (id, name, status, dateModified) 
    VALUES (@id, @name, @status, SYSUTCDATETIME()) 

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

ответ

10

Вы просто не можете сделать это. MERGE работает только на двух таблицах - источнике и цели.

Для вашего требования вам необходимо, например, используйте CTE (Common Table Expression), чтобы найти строки, которые не совпадают, и вставьте их в третью таблицу.

Что-то вроде:

;WITH NonMatchedData AS 
(
    -- adapt this as needed - just determine which rows match your criteria, 
    -- and make sure to return all the columns necessary for the subsequent INSERT 
    SELECT (columns) 
    FROM dbo.SourceTable 
    WHERE ID NOT IN (SELECT DISTINCT ID FROM dbo.TargetTable) 
) 
INSERT INTO dbo.ThirdTable(Col1, Col2, ....., ColN) 
    SELECT Col1, Col2, ....., ColN 
    FROM NonMatchedData 
+1

Есть ли альтернатива 'NOT IN' в этом случае? Что-то вроде 'JOIN', который перенастраивает все строки, которые не были' JOIN'? Другой, тогда 'LEFT JOIN' +' IS NULL'. Кроме того, нужен ли CTE? Разве он не может «ВСТАВИТЬСЯ В ОТКРЫТИЕ ОТ ВЫБРАТЬ NonMatchedData»? – Alexandre

+1

@PeekaySwitch: конечно - но тогда вы ** ARE ** выполняете 'LEFT OUTER JOIN' и проверяете, что столбец из' dbo.TargetTable' является 'NULL' .... Я не вижу, какой другой вариант быть там, действительно .... –

+1

Знаете ли вы, что на вершине вашей головы есть лучшие возможности? Я ожидал бы, что 'LEFT OUTER JOIN' будет более эффективным, но, возможно, они близки друг к другу, я просто старался избегать использования' NOT IN' с огромными количествами данных в 'Where' (Like ID) – Alexandre

2

Вы можете сделать это очень легко ...

Вы можете обернуть заявление MERGE в INSERT INTO FROM:
http://technet.microsoft.com/en-us/library/bb510625.aspx#sectionToggle2

-ИЛИ-

Вы можете сделать это непосредственно в заявлении о слиянии:

Быстрый пример:

WHEN NOT MATCHED THEN 
    DELETE 
OUTPUT Deleted.* INTO dbo.MyTable; 

Это вставит не-спички в существующую таблицу назначения. Вы можете использовать те Обновленные, Вставленные, Удаленные v-таблицы, чтобы направлять данные в другие места.

+0

Это должно быть как предложение 'MATCHED', так и' NOT MATCHED BY SOURCE', но это делает трюк. –

Смежные вопросы