通过重用 postgres 索引或 bigserial 将数据从 staging table 插入到 2 tables
insert data from staging table to 2 tables by reusing postgres index or bigserial
我有 3 张桌子:
CREATE TABLE stage
(
a1 text,
b2 text,
c3 text,
d4 text,
e5 text
);
CREATE TABLE main
(
id bigserial PRIMARY KEY,
a1 text,
b2 text,
c3 text
);
CREATE TABLE secondary (
id bigserial PRIMARY KEY,
mainid bigint,
d4 text,
e5 text,
CONSTRAINT secondary_fkey FOREIGN KEY(mainid) REFERENCES main(id)
);
我想立即将 stage
中的数据插入 main
和 secondary
,但我不太确定如何通过在 [=14= 中重用生成的 bigserial 来做到这一点].我正在尝试 with query
,但我在 secondary
中获得的行(指数)比预期的多。
WITH tmp AS (
INSERT INTO
main (a1, b2, c3)
SELECT
a1,
b2,
c3
FROM
stage RETURNING id
)
INSERT INTO
secondary (mainid, d4, e5)
SELECT
tmp.id,
stage.d4,
stage.e5
FROM
tmp,
stage;
您的问题是您在最终 INSERT
语句中创建的与 FROM tmp, stage;
的交叉连接。如果您在阶段中有 10 行 table,这将生成 100 行而不是您想要的 10 行。
如果 (a1, b2, c3)
唯一标识 stage
中的一行,您可以将它们用于适当的连接条件:
WITH tmp AS (
INSERT INTO main (a1, b2, c3)
SELECT a1, b2, c3
FROM stage
RETURNING *
)
INSERT INTO secondary (mainid, d4, e5)
SELECT tmp.id,
stage.d4,
stage.e5
FROM tmp
JOIN stage
on tmp.a1 = stage.a1
and tmp.b2 = stage.b2
and tmp.c3 = stage.c3;
如果那不可行(因为存在重复项),您可以为 main
table 在 插入之前使用 nextval()
with stage_with_mainid as (
select nextval(pg_get_serial_sequence('main', 'id')) as mainid,
a1, b2, c3, d4, e5
from stage
), insert_main as (
insert into main (id, a1, b2, c3) --<< this provides the generated new ID explictely
select mainid, a1, b2, c3
from stage_with_mainid
)
insert into secondary (mainid, d4, e5)
select mainid, d4, e5
from stage_with_mainid;
我有 3 张桌子:
CREATE TABLE stage
(
a1 text,
b2 text,
c3 text,
d4 text,
e5 text
);
CREATE TABLE main
(
id bigserial PRIMARY KEY,
a1 text,
b2 text,
c3 text
);
CREATE TABLE secondary (
id bigserial PRIMARY KEY,
mainid bigint,
d4 text,
e5 text,
CONSTRAINT secondary_fkey FOREIGN KEY(mainid) REFERENCES main(id)
);
我想立即将 stage
中的数据插入 main
和 secondary
,但我不太确定如何通过在 [=14= 中重用生成的 bigserial 来做到这一点].我正在尝试 with query
,但我在 secondary
中获得的行(指数)比预期的多。
WITH tmp AS (
INSERT INTO
main (a1, b2, c3)
SELECT
a1,
b2,
c3
FROM
stage RETURNING id
)
INSERT INTO
secondary (mainid, d4, e5)
SELECT
tmp.id,
stage.d4,
stage.e5
FROM
tmp,
stage;
您的问题是您在最终 INSERT
语句中创建的与 FROM tmp, stage;
的交叉连接。如果您在阶段中有 10 行 table,这将生成 100 行而不是您想要的 10 行。
如果 (a1, b2, c3)
唯一标识 stage
中的一行,您可以将它们用于适当的连接条件:
WITH tmp AS (
INSERT INTO main (a1, b2, c3)
SELECT a1, b2, c3
FROM stage
RETURNING *
)
INSERT INTO secondary (mainid, d4, e5)
SELECT tmp.id,
stage.d4,
stage.e5
FROM tmp
JOIN stage
on tmp.a1 = stage.a1
and tmp.b2 = stage.b2
and tmp.c3 = stage.c3;
如果那不可行(因为存在重复项),您可以为 main
table 在 插入之前使用 nextval()
with stage_with_mainid as (
select nextval(pg_get_serial_sequence('main', 'id')) as mainid,
a1, b2, c3, d4, e5
from stage
), insert_main as (
insert into main (id, a1, b2, c3) --<< this provides the generated new ID explictely
select mainid, a1, b2, c3
from stage_with_mainid
)
insert into secondary (mainid, d4, e5)
select mainid, d4, e5
from stage_with_mainid;