125

次の2つのテーブルがあります。

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

ただし、私の場合は、重複するIDが存在する可能性があり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ある条件に基づいて2つのステートメントを避けたい。

4

10 に答える 10

243

使用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

3つのオプションのうち、LEFT JOIN/IS NULLは効率が低くなります。詳細については、このリンクを参照してください

于 2010-03-25T05:07:34.857 に答える
40

MySQLではこれを行うことができます:

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

SQL Serverに似たようなものはありますか?

于 2010-03-25T06:24:56.853 に答える
7

同様の問題が発生しました。DISTINCTキーワードは魔法のように機能します。

INSERT INTO Table2(Id, Name) SELECT DISTINCT Id, Name FROM Table1
于 2016-07-15T22:10:10.460 に答える
5

最近同じ問題に直面していました...
MSSQLServer2017で機能したものは
次のとおりです...主キーは表2のIDに設定する必要があります...
列と列のプロパティはもちろん両方の間で同じである必要がありますテーブル。これは、以下のスクリプトを初めて実行するときに機能します。表1の重複IDは挿入されません...

2回目に実行すると、

PRIMARYKEY制約エラーの違反

これはコードです:

Insert into Table_2
Select distinct *
from Table_1
where table_1.ID >1
于 2018-10-20T22:14:53.793 に答える
4

ここでIanCによって提案されignore Duplicatesた一意のインデックスを使用することは、同様の問題に対する私の解決策であり、オプションを使用してインデックスを作成しましたWITH IGNORE_DUP_KEY

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

参照:index_option

于 2015-01-14T16:41:14.127 に答える
4

SQL Serverから、(一意である必要がある列)のテーブルに一意キーインデックスを設定できます。

SQLサーバーからテーブルデザインを右クリックし、インデックス/キーを選択します

重複しない列を選択し、UniqueKeyと入力します

于 2016-07-31T08:09:14.367 に答える
2

少し外れたトピックですが、データを新しいテーブルに移行する必要があり、重複する可能性のあるものが元のテーブルにあり、重複する可能性のある列がIDでない場合は、次のGROUP BYようになります。

INSERT INTO TABLE_2
(name)
  SELECT t1.name
  FROM TABLE_1 t1
  GROUP BY t1.name
于 2018-01-30T15:43:17.353 に答える
0

私の場合、ソーステーブルに重複したIDがあったため、どの提案も機能しませんでした。私はパフォーマンスを気にしません、それは一度だけ行われます。これを解決するために、重複を無視するためにカーソルを使用してレコードを1つずつ取得しました。

したがって、コード例は次のとおりです。

DECLARE @c1 AS VARCHAR(12);
DECLARE @c2 AS VARCHAR(250);
DECLARE @c3 AS VARCHAR(250);


DECLARE MY_cursor CURSOR STATIC FOR
Select
c1,
c2,
c3
from T2
where ....;

OPEN MY_cursor
FETCH NEXT FROM MY_cursor INTO @c1, @c2, @c3

WHILE @@FETCH_STATUS = 0
BEGIN
    if (select count(1) 
        from T1
        where a1 = @c1
        and a2 = @c2
        ) = 0 
            INSERT INTO T1
            values (@c1, @c2, @c3)

    FETCH NEXT FROM MY_cursor INTO @c1, @c2, @c3
END
CLOSE MY_cursor
DEALLOCATE MY_cursor
于 2020-10-14T19:59:21.893 に答える
0

MERGEクエリを使用して、重複することなくテーブルを埋めました。私が抱えていた問題は、テーブル(Code、Value)のダブルキーであり、existsクエリは非常に低速でした。MERGEは非常に高速に実行されました(X100以上)。

MERGEクエリの例

于 2021-04-12T13:25:20.693 に答える
-6

簡単なDELETE前にINSERT十分です:

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

保持するテーブルとペアリングTable1Table2応じて切り替えます。Idname

于 2018-11-14T01:43:43.480 に答える