sql >> Databáze >  >> RDS >> PostgreSQL

VLOŽTE řádky do více tabulek v jediném dotazu a vybírejte ze zapojené tabulky

Konečná verze

... po dalších informacích z OP. Zvažte toto demo:

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

Vložit hodnoty - bar za prvé.
Bylo by to velmi užitečné pokud jste ve své otázce takto poskytli testovací data!

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

Nastavte sekvence na aktuální hodnoty, jinak dojde k duplicitnímu porušení klíče:

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

Kontroly:

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

Dotaz:

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

To by mělo odpovídat tomu, co popisuje vaše poslední aktualizace.

Dotaz předpokládá, že z je UNIQUE . Pokud z není unikátní, je složitější. Připravené řešení pomocí funkce okna row_number() naleznete v dotazu 2 v této související odpovědi. v tomto případě.

Zvažte také nahrazení vztahu 1:1 mezi foo a bar s jednou sjednocenou tabulkou.

Úpravy dat CTE

Druhá odpověď po dalších informacích.

Pokud chcete přidat řádky do foo a bar v jediném dotazu můžete použít data upravující CTE 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;

Hodnoty čerpám z foo , vložte je do bar , nechte je vrátit spolu s automaticky vygenerovaným bar_id a vložte to do foo . Můžete použít i jakákoli jiná data.

Zde je funkční demo, se kterým si můžete zahrát na sqlfiddle.

Základy

Původní odpověď se základními informacemi před upřesněním.
Základní tvar je:

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

Nejsou potřeba závorky. Totéž můžete udělat s jakoukoli tabulkou

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

A můžete se připojit k tabulce, do které vkládáte, v 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

Je to prostě SELECT jako každý jiný - který může zahrnovat tabulku, do které vkládáte. Řádky jsou nejprve přečteny a poté vloženy.



  1. Python:osvědčený postup a nejbezpečnější způsob připojení k MySQL a provádění dotazů

  2. Jak najdu datový adresář pro instanci SQL Server?

  3. Nejrychlejší metoda pro SQL Server vkládá, aktualizuje, vybírá

  4. Jak se vzdáleně připojit k databázi MySQL umístěné na našem sdíleném serveru