PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

WSTAW wiersze do wielu tabel w jednym zapytaniu, wybierając z zaangażowanej tabeli

Wersja ostateczna

... po więcej informacji z OP. Rozważ tę prezentację:

-- 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)
);

Wstaw wartości - bar po pierwsze.
Byłoby to bardzo pomocne jeśli podałeś dane testowe w swoim pytaniu w ten sposób!

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);

Ustaw sekwencje na bieżące wartości lub otrzymamy zduplikowane naruszenia klawiszy:

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

Czeki:

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

Zapytanie:

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);

Powinno to zrobić to, co opisuje Twoja ostatnia aktualizacja.

Zapytanie zakłada, że ​​z jest UNIQUE . Jeśli z nie jest wyjątkowy, staje się bardziej złożony. Zapoznaj się z zapytaniem 2 w tej powiązanej odpowiedzi, aby uzyskać gotowe rozwiązanie za pomocą funkcji okna row_number() w tym przypadku.

Rozważ także zastąpienie relacji 1:1 między foo i bar z jednym wspólnym stołem.

Modyfikowanie danych CTE

Druga odpowiedź po więcej informacji.

Jeśli chcesz dodać wiersze do foo i bar w pojedynczym zapytaniu możesz użyć CTE modyfikującego dane od 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;

Rysuję wartości z foo , wstaw je w bar , zwróć je razem z automatycznie wygenerowanym bar_id i wstaw to w foo . Możesz również użyć dowolnych innych danych.

Oto działające demo do zabawy na sqlfiddle.

Podstawy

Oryginalna odpowiedź z podstawowymi informacjami przed wyjaśnieniami.
Podstawowa forma to:

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

Nie potrzeba nawiasów. To samo możesz zrobić z dowolną tabelą

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

I możesz dołączyć do tabeli, do której wstawiasz w 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

To po prostu SELECT jak każda inna — może zawierać tabelę, do której wstawiasz. Wiersze są najpierw odczytywane, a następnie wstawiane.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak uzyskać aktualny czas (bez strefy czasowej) w PostgreSQL

  2. Jak pogrupować znaczniki czasu w wyspy (na podstawie arbitralnej luki)?

  3. Śledzenie wysokiej dostępności PostgreSQL za pomocą funkcji Heartbeat

  4. konwertuj format geometrii Postgres na WKT

  5. Porównanie magazynów danych dla PostgreSQL — MVCC vs InnoDB