web-dev-qa-db-de.com

Vermeiden Sie Duplikate in der INSERT INTO SELECT-Abfrage in SQL Server

Ich habe die folgenden zwei Tabellen:

Table1
----------
ID   Name
1    A
2    B
3    C

Table2
----------
ID   Name
1    Z

Ich muss Daten von Table1 in Table2 einfügen. Ich kann folgende Syntax verwenden:

INSERT INTO Table2(Id, Name) SELECT Id, Name FROM Table1

In meinem Fall sind jedoch möglicherweise doppelte IDs in Table2 vorhanden (in meinem Fall ist es nur "1") und ich möchte diese nicht erneut kopieren, da dies einen Fehler auslösen würde. 

Ich kann so etwas schreiben:

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

Gibt es einen besseren Weg, dies ohne IF - ELSE zu tun? Ich möchte zwei INSERT INTO-SELECT-Anweisungen vermeiden, die auf einer bestimmten Bedingung basieren.

88
Ashish Gupta

NOT EXISTS verwenden:

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 verwenden:

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 verwenden:

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

Von den drei Optionen ist der LEFT JOIN/IS NULL weniger effizient. Siehe diesen Link für weitere Details .

171
OMG Ponies

In MySQL können Sie Folgendes tun:

INSERT IGNORE INTO Table2(Id, Name) SELECT Id, Name FROM Table1

Hat SQL Server etwas Ähnliches?

27
Duncan

Ich hatte gerade ein ähnliches Problem, das DISTINCT-Schlüsselwort wirkt magisch:

INSERT INTO Table2(Id, Name) SELECT DISTINCT Id, Name FROM Table1
6
Hunter Bingham

Die Verwendung von ignore Duplicates für den eindeutigen Index wie von IanC hier vorgeschlagen war meine Lösung für ein ähnliches Problem, indem der Index mit der Option WITH IGNORE_DUP_KEY erstellt wurde.

In backward compatible syntax
, WITH IGNORE_DUP_KEY is equivalent to WITH IGNORE_DUP_KEY = ON.

Ref .: index_option

3
Tazz602

Von SQL Server aus können Sie einen Unique-Schlüssel - Index für die Tabelle festlegen für

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

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

3
M. Salah

Ich hatte kürzlich das gleiche Problem ...
Was für mich in MS SQL Server 2017 funktionierte ...
.__ Der Primärschlüssel sollte in Tabelle 2 auf ID gesetzt werden ...
.__ Die Spalten- und Spalteneigenschaften sollten natürlich zwischen den beiden Tabellen gleich sein. Dies funktioniert, wenn Sie das folgende Skript zum ersten Mal ausführen. Die doppelte ID in Tabelle 1 wird nicht eingefügt ...

Wenn Sie es das zweite Mal ausführen, erhalten Sie eine 

Verletzung des PRIMARY KEY-Einschränkungsfehlers

Dies ist der Code:

Insert into Table_2
Select distinct *
from Table_1
where table_1.ID >1
2
Vishane Naicker

Eine einfache DELETE vor der INSERT würde ausreichen:

DELETE FROM Table2 WHERE Id = (SELECT Id FROM Table1)
INSERT INTO Table2 (Id, name) SELECT Id, name FROM Table1

Ändern Sie Table1 für Table2, je nachdem, welche Id- und name-Tabelle Sie verwenden möchten.

0
Sacro

Ein kleines Thema, aber wenn Sie die Daten in eine neue Tabelle migrieren möchten und sich die möglichen Duplikate in der ursprünglichen Tabelle befinden , und die möglicherweise duplizierte Spalte keine ID ist, wird ein GROUP BY ausgeführt:

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