Избегайте дублирования при вставке в запрос 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 81

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

из SQL Server вы можете установить уникальный ключ индекс в таблице для (столбцов, которые должны быть уникальными)

From sql server right click on the table design select Indexes/Keys

Select column(s) that will be not duplicate , then type Unique Key

немного не по теме, но если вы хотите перенести данные в новую таблицу, и возможные дубликаты в исходной таблице, и столбец, возможно, дублируется не идентификатор, а GROUP BY будет делать:

INSERT INTO TABLE_2
(name)
  SELECT t1.name
  FROM TABLE_1 t1
  GROUP BY t1.name