PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Masukkan data dalam 3 tabel sekaligus menggunakan Postgres

Gunakan CTE pengubah data :

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;

Setiap INSERT tergantung yang dulu. SELECT bukannya VALUES memastikan tidak ada yang dimasukkan dalam tabel tambahan jika tidak ada baris yang dikembalikan dari INSERT sebelumnya . (Sejak Postgres 9.5+ Anda dapat menambahkan ON CONFLICT .)
Ini juga sedikit lebih pendek dan lebih cepat.

Biasanya, lebih mudah menyediakan baris data lengkap di satu tempat :

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<>main biola di sini

Anda mungkin memerlukan pemeran tipe eksplisit dalam VALUES yang berdiri sendiri ekspresi - sebagai lawan dari VALUES ekspresi yang dilampirkan ke INSERT di mana tipe data berasal dari tabel target. Lihat:

  • Mentransmisikan jenis NULL saat memperbarui beberapa baris

Jika beberapa baris bisa datang dengan identik (firstname, lastname) , Anda mungkin perlu melipat duplikat untuk INSERT first pertama :

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

Anda dapat menggunakan tabel (sementara) sebagai sumber data alih-alih data CTE .

Mungkin masuk akal untuk menggabungkan ini dengan batasan UNIK pada (firstname, lastname) dalam tabel dan ON CONFLICT klausa dalam kueri.

Terkait:

  • Bagaimana cara menggunakan RETURNING dengan ON CONFLICT di PostgreSQL?
  • Apakah SELECT atau INSERT dalam fungsi rentan terhadap kondisi balapan?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. di postgres, dapatkah Anda mengatur pemformatan default untuk stempel waktu, berdasarkan sesi atau secara global?

  2. Kesalahan saat menghubungkan ke postgresql menggunakan sqlalchemy

  3. Bagaimana cara memasukkan pandas DataFrame ke tabel PostgreSQL?

  4. Postgres:INSERT jika belum ada

  5. Gabungkan dua kolom dan tambahkan menjadi satu kolom baru