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

Postgresを使用して一度に3つのテーブルにデータを挿入します

    データ変更CTEを使用する :

    WITH ins1 AS (
       INSERT INTO sample(firstname, lastname)
       VALUES ('fai55', 'shaggk')
    -- ON     CONFLICT DO NOTHING         -- optional addition in Postgres 9.5+
       RETURNING id AS sample_id
       )
    , ins2 AS (
       INSERT INTO sample1 (sample_id, adddetails)
       SELECT sample_id, 'ss' FROM ins1
       RETURNING user_id
       )
    INSERT INTO sample2 (user_id, value)
    SELECT user_id, 'ss2' FROM ins2;
    

    INSERT 前のものに依存します。 SELECT VALUESの代わりに 前のINSERTから行が返されない場合は、補助テーブルに何も挿入されないようにします 。 (Postgres 9.5以降では、ON CONFLICTを追加できます。 。)
    この方法では、少し短くて高速です。

    通常、完全なデータ行を1か所に提供する方が便利です。

    WITH data(firstname, lastname, adddetails, value) AS (
       VALUES                              -- provide data here
          ('fai55', 'shaggk', 'ss', 'ss2') -- see below
        , ('fai56', 'XXaggk', 'xx', 'xx2') -- works for multiple input rows
           --  more?                      
       )
    , ins1 AS (
       INSERT INTO sample (firstname, lastname)
       SELECT firstname, lastname          -- DISTINCT? see below
       FROM   data
       -- ON     CONFLICT DO NOTHING       -- UNIQUE constraint? see below
       RETURNING firstname, lastname, id AS sample_id
       )
    , ins2 AS (
       INSERT INTO sample1 (sample_id, adddetails)
       SELECT ins1.sample_id, d.adddetails
       FROM   data d
       JOIN   ins1 USING (firstname, lastname)
       RETURNING sample_id, user_id
       )
    INSERT INTO sample2 (user_id, value)
    SELECT ins2.user_id, d.value
    FROM   data d
    JOIN   ins1 USING (firstname, lastname)
    JOIN   ins2 USING (sample_id);
    

    db<>ここでフィドル

    スタンドアロンのVALUESで明示的な型キャストが必要になる場合があります 式-VALUESとは対照的 INSERTに付加された式 ここで、データ型はターゲットテーブルから派生します。参照:

    • 複数の行を更新するときにNULLタイプをキャストする

    複数の行に同じ(firstname, lastname)を付けることができる場合 、最初のINSERTの重複を折りたたむ必要がある場合があります :

    ...
    INSERT INTO sample (firstname, lastname)
    SELECT DISTINCT firstname, lastname FROM data
    ...
    

    CTE dataの代わりに、(一時的な)テーブルをデータソースとして使用できます。 。

    これを(firstname, lastname)のUNIQUE制約と組み合わせるのはおそらく理にかなっています。 テーブルとON CONFLICT クエリの句。

    関連:

    • PostgreSQLでONCONFLICTを使用してRETURNINGを使用するにはどうすればよいですか?
    • 関数内のSELECTまたはINSERTは競合状態になりやすいですか?


    1. 行の目標、パート3:アンチ結合

    2. MySQLで照合を見つける方法

    3. Oracle DB Server + APEX + ORDS + JasperReportsをゼロから(パート4)

    4. Postgres:まだ存在しない場合はINSERT