Ich schreibe einen Job, um Daten von einem alten Design in ein neues Design umzuwandeln. In diesem Prozess muss ich die ID aus einer Einfügung in eine separate Tabelle übernehmen und diese in einer Einfügung in die Zieltabelle als solche verwenden:
CREATE TABLE t1 {
t1_id BIGSERIAL,
col1 VARCHAR
};
CREATE TABLE t2 {
t2_id BIGSERIAL,
col2 VARCHAR, -- renamed from col1 to avoid confusion
t1_id BIGINT REFERENCES t1.t1_id
};
Ich habe die SQL definiert, die der folgenden Form entspricht:
WITH ins AS (
INSERT INTO t1 (t1_id) VALUES (DEFAULT) RETURNING t1_id
) INSERT INTO t2
(col1, t1_id)
SELECT
a.val1, (SELECT * FROM ins)
FROM t3 a;
Ich wollte, dass dies SELECT * FROM ins
für jede Zeile des SELECT
.. ausgeführt wird, aber stattdessen wird es nur einmal ausgeführt und verwendet diesen Wert für alle Zeilen im SELECT
. Wie kann ich mein SQL umstrukturieren, um das gewünschte Verhalten zu erzielen?
edit4
t1 sieht am Ende so aus:
1,<NULL>
(1 row)
t2 sieht am Ende so aus:
10,'a',1
11,'b',1 -- problem with id from t1 being 1
12,'c',1 -- problem with id from t1 being 1
.
.
Wie soll t1 aussehen:
1,<NULL>
2,<NULL>
3,<NULL>
.
.
Wie soll t2 aussehen:
10,'a',1
11,'b',2 -- id from t1 of 2
12,'c',3 -- id from t1 of 3
.
.
edit Um zu adressieren, was a_horse_with_no_name gesagt hat, habe ich auch Folgendes versucht (mit dem gleichen Ergebnis):
WITH ins AS (
INSERT INTO t1 (t1_id) VALUES (DEFAULT) RETURNING t1_id
) INSERT INTO t2
(col1, t1_id)
SELECT
a.val1, b.t1_id
FROM t3 a
JOIN ins b ON TRUE;
edit2
Ich habe gerade versucht, SEQUENCE
in meiner Abfrage direkt auf das entsprechende zu verweisen, und das funktioniert - aber ich mag diese Lösung überhaupt nicht sehr (hauptsächlich, weil ich keine hartcodierten Objektnamen mag.) Wenn es eine andere Lösung gibt als direkt auf den Namen des zu verweisen, SEQUENCE
würde ich es schätzen. :) :)
EDIT3
Ich nehme eine andere Lösung wäre die Verwendung eines machen PROCEDURE
das zu tun , INSERT
anstelle eines CTE .. aber ich würde immer noch Anerkennung Optionen / Vorschläge.
quelle
ins
undt3
t1
und geben keinen Wert für eint1.col1
. Woher sollen die Daten für diese Spalte kommen? Istt1.col1
verwandt mitt2.col1
?INSERT INTO t1 (t1_id) VALUES (DEFAULT)
nur 1 Zeile in eint1
. Es spielt also keine Rolle, ob Sie dasins
in dieFROM
Klausel einfügen und es verbindent3
oder nicht. Können Sie uns zeigen, wie Sie 2 (oder mehr) Zeilen einfügen würdent1
? Und was noch wichtiger ist: Woher wissen Sie, welcher der 2 (oder mehr)t1.id
Werte mit den eingefügten Zeilen übereinstimmtt2
?Antworten:
Ich verstehe nicht, warum Sie 2 Tabellen benötigen, wenn sie nur 1-1 Beziehung haben. Aber hier ist es (
pk
ist der Primärschlüssel vont3
):Wenn Ihr t3 das Ergebnis eines SELECT anstelle einer bereits vorhandenen Tabelle ist, können Sie es als solches implementieren, sodass Sie die t3-Abfrage nicht zweimal wiederholen müssen:
quelle
t2_id
überhaupt nicht. Scheint, Sie können diet2(t1_id)
als PK von verwendent2
.ERROR: syntax error at or near "DEFAULT" LINE 2: DEFAULT AS contact_detail_id
DEFAULT
nicht so zu sein. Noch diet.pk