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

MASUKKAN baris ke dalam beberapa tabel dalam satu kueri, pilih dari tabel yang terlibat

Versi final

... setelah beberapa info lebih lanjut dari OP. Pertimbangkan demo ini:

-- DROP TABLE foo; DROP TABLE bar;

CREATE TEMP TABLE bar (
 id serial PRIMARY KEY  -- using a serial column!
,z  integer NOT NULL
);

CREATE TEMP TABLE foo (
 id     serial PRIMARY KEY  -- using a serial column!
,x      integer NOT NULL
,y      integer NOT NULL
,bar_id integer UNIQUE NOT NULL REFERENCES bar(id)
);

Masukkan nilai - bar pertama.
Akan sangat membantu jika Anda memberikan data uji dalam pertanyaan Anda seperti ini!

INSERT INTO bar (id,z) VALUES
 (100, 7)
,(101,16)
,(102,21);

INSERT INTO foo (id, x, y, bar_id) VALUES
 (1, 3,4,100)
,(2, 9,6,101)
,(3,18,0,102);

Setel urutan ke nilai saat ini atau kami mendapatkan pelanggaran kunci duplikat:

SELECT setval('foo_id_seq', 3);
SELECT setval('bar_id_seq', 102);

Cek:

-- SELECT nextval('foo_id_seq')
-- SELECT nextval('bar_id_seq')
-- SELECT * from bar;
-- SELECT * from foo;

Pertanyaan:

WITH a AS (
    SELECT f.x, f.y, bar_id, b.z
    FROM   foo f
    JOIN   bar b ON b.id = f.bar_id
    WHERE  x > 3
    ),b AS (
    INSERT INTO bar (z)
    SELECT z
    FROM   a
    RETURNING z, id AS bar_id
    )
INSERT INTO foo (x, y, bar_id)
SELECT a.x, a.y, b.bar_id
FROM   a
JOIN   b USING (z);

Ini akan melakukan apa yang dijelaskan oleh pembaruan terakhir Anda.

Kueri mengasumsikan bahwa z adalah UNIQUE . Jika z tidak unik, itu menjadi lebih kompleks. Lihat Kueri 2 dalam jawaban terkait ini untuk solusi siap pakai menggunakan fungsi jendela row_number() dalam hal ini.

Juga, pertimbangkan untuk mengganti relasi 1:1 antara foo dan bar dengan satu meja bersatu.

CTE memodifikasi data

Jawaban kedua setelah info lebih lanjut.

Jika Anda ingin menambahkan baris ke foo dan bar dalam satu kueri, Anda dapat menggunakan CTE yang memodifikasi data sejak PostgreSQL 9.1 :

WITH x AS (
    INSERT INTO bar (col1, col2)
    SELECT f.col1, f.col2
    FROM   foo f
    WHERE  f.id BETWEEN 12 AND 23 -- some filter
    RETURNING col1, col2, bar_id  -- assuming bar_id is a serial column
    )
INSERT INTO foo (col1, col2, bar_id)
SELECT col1, col2, bar_id
FROM   x;

Saya mengambil nilai dari foo , masukkan di bar , minta mereka kembali bersama dengan bar_id . yang dibuat secara otomatis dan masukkan itu ke foo . Anda juga dapat menggunakan data lain.

Berikut adalah demo yang berfungsi untuk dimainkan di sqlfiddle.

Dasar

Jawaban asli dengan informasi dasar sebelum klarifikasi.
Bentuk dasarnya adalah:

INSERT INTO foo (...)
SELECT ... FROM foo WHERE ...

Tidak perlu tanda kurung. Anda dapat melakukan hal yang sama dengan tabel apa pun

INSERT INTO foo (...)
SELECT ... FROM bar WHERE ...

Dan Anda dapat bergabung ke tabel yang Anda masukkan ke dalam SELECT:

INSERT INTO foo (...)
SELECT f.col1, f.col2, .. , b.bar_id
FROM   foo f
JOIN   bar b USING (foo_id);  -- present in foo and bar

Ini hanya SELECT seperti yang lain - yang dapat menyertakan tabel yang Anda masukkan. Baris pertama dibaca, lalu disisipkan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Penyesuaian PostgreSQL:Hal Utama untuk Mendorong Kinerja

  2. Di Postgresql, paksa unik pada kombinasi dua kolom

  3. Postgresql mengubah jenis kolom dari int ke UUID

  4. Perintah PostgreSQL VALUES Dijelaskan

  5. Cara melakukan operasi pembaruan pada kolom tipe JSONB di Postgres 9.4