sql >> データベース >  >> RDS >> PostgreSQL

複数の行を挿入すると、重複はどうなりますか?

    INSERT すべての行を挿入するだけで、何もありません ただしでない限り、特別なことが起こります ある種の制約があります 重複/重複する値を禁止する(PRIMARY KEYUNIQUECHECK またはEXCLUDE 制約)-あなたはあなたの質問で言及しませんでした。しかし、それはおそらくあなたが心配していることです。

    UNIQUEを想定 または(col1,col2)のPK制約 、教科書UPSERTを扱っています 状況。ここで見つけるための多くの関連する質問と回答。

    一般的に、 any 制約に違反すると、例外が発生します(plpgsqlなどの手続き型サーバー側言語で可能なようにサブトランザクションにトラップされない限り)ステートメントだけでなく、トランザクション全体もロールバックします。

    同時書き込みなし

    つまり、他のトランザクションが同時に同じテーブルに書き込もうとすることはありません。

    • WHERE NOT EXISTS ...を使用してテーブルにすでに存在する行を除外します またはその他の適用可能な手法:

    • 他のテーブルに存在しない行を選択してください

    • また、の重複を削除することを忘れないでください 挿入されたセットもありません セミアンチジョインによって除外されるWHERE NOT EXISTS ...

    両方を同時に処理する1つの手法は、EXCEPTです。 :

    INSERT INTO tbl (col1, col2)
    VALUES
      (text 'v1', text 'v2')  -- explicit type cast may be needed in 1st row
    , ('v3', 'v4')
    , ('v3', 'v4')  -- beware of dupes in source
    EXCEPT SELECT col1, col2 FROM tbl;
    

    EXCEPT キーワードALLなし ソース内の重複する行を折ります。重複がないことがわかっている場合、または重複をサイレントに折りたたむ必要がない場合は、EXCEPT ALLを使用してください (または他の手法の1つ)。参照:

    • PostgreSQLでEXCEPT句を使用する

    一般に、ターゲットテーブルが大きい場合 、WHERE NOT EXISTS DISTINCTと組み合わせて ソース上でおそらくより速くなります:

    INSERT INTO tbl (col1, col2)
    SELECT *
    FROM  (
       SELECT DISTINCT *
       FROM  (
           VALUES
             (text 'v1', text'v2')
           , ('v3', 'v4')
           , ('v3', 'v4')  -- dupes in source
          ) t(c1, c2)
       ) t
    WHERE NOT EXISTS (
       SELECT FROM tbl
       WHERE  col1 = t.c1 AND col2 = t.c2
       );
    

    重複が多数ある可能性がある場合は、最初にソースでそれらを折りたたむことをお勧めします。それ以外の場合は、1つのサブクエリを使用します。

    関連:

    • 他のテーブルに存在しない行を選択します

    同時書き込みあり

    PostgresのUPSERTを使用する 実装INSERT ... ON CONFLICT ... Postgres 9.5 以降:

    INSERT INTO tbl (col1,col2)
    SELECT DISTINCT *  -- still can't insert the same row more than once
    FROM  (
       VALUES
         (text 'v1', text 'v2')
       , ('v3','v4')
       , ('v3','v4')  -- you still need to fold dupes in source!
      ) t(c1, c2)
    ON CONFLICT DO NOTHING;  -- ignores rows with *any* conflict!
    

    さらに読む:

    • PostgreSQLでONCONFLICTを使用してRETURNINGを使用するにはどうすればよいですか?
    • 外部キーを含む行を挿入するにはどうすればよいですか?

    ドキュメント:

    • マニュアル
    • コミットページ
    • PostgresWikiページ

    UPSERTに対するCraigのリファレンスアンサー 問題:

    • PostgreSQLでUPSERT(MERGE、INSERT ... ON DUPLICATE UPDATE)する方法


    1. Oracle:JMSメッセージを送信するJavaストアドプロシージャ

    2. pipを使用してPythonMySQLdbモジュールをインストールするにはどうすればよいですか?

    3. IDを使用して複数のSQLテーブルを結合するにはどうすればよいですか?

    4. SQLServerのデータベースのすべてのテーブル間の関係を知る