Избегайте дублирования при вставке в запрос SELECT в SQL Server
у меня есть следующие две таблицы:
Table1
----------
ID Name
1 A
2 B
3 C
Table2
----------
ID Name
1 Z
мне нужно вставить данные из Table1
до Table2
. Я могу использовать следующий синтаксис:
INSERT INTO Table2(Id, Name) SELECT Id, Name FROM Table1
однако, в моем случае, дубликаты идентификаторов могут существовать в Table2
(в моем случае, это просто "1
") и я не хочу копировать это снова, так как это вызовет ошибку.
Я могу написать что-то вроде этого:
IF NOT EXISTS(SELECT 1 FROM Table2 WHERE Id=1)
INSERT INTO Table2 (Id, name) SELECT Id, name FROM Table1
ELSE
INSERT INTO Table2 (Id, name) SELECT Id, name FROM Table1 WHERE Table1.Id<>1
есть ли лучший способ сделать это без использования IF - ELSE
? Я хочу избежать двух INSERT INTO-SELECT
заявления, основанные на некотором условии.
6 ответов:
используя
NOT EXISTS
:INSERT INTO TABLE_2 (id, name) SELECT t1.id, t1.name FROM TABLE_1 t1 WHERE NOT EXISTS(SELECT id FROM TABLE_2 t2 WHERE t2.id = t1.id)
используя
NOT IN
:INSERT INTO TABLE_2 (id, name) SELECT t1.id, t1.name FROM TABLE_1 t1 WHERE t1.id NOT IN (SELECT id FROM TABLE_2)
используя
LEFT JOIN/IS NULL
:INSERT INTO TABLE_2 (id, name) SELECT t1.id, t1.name FROM TABLE_1 t1 LEFT JOIN TABLE_2 t2 ON t2.id = t1.id WHERE t2.id IS NULL
из трех вариантов
LEFT JOIN/IS NULL
менее эффективен. Смотрите эта ссылка для более подробной информации.
в MySQL вы можете сделать это:
INSERT IGNORE INTO Table2(Id, Name) SELECT Id, Name FROM Table1
есть ли у SQL Server что-нибудь подобное?
У меня просто была аналогичная проблема, ключевое слово DISTINCT works magic:
INSERT INTO Table2(Id, Name) SELECT DISTINCT Id, Name FROM Table1
используя
ignore Duplicates
по уникальному индексу как предложил IanC здесь было мое решение для аналогичной проблемы, создание индекса с опциейWITH IGNORE_DUP_KEY
In backward compatible syntax , WITH IGNORE_DUP_KEY is equivalent to WITH IGNORE_DUP_KEY = ON.
Ref.:index_option