0

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

我想一次插入数据,stagemainsecondary不太确定如何通过重用生成的 bigserial in 来做到这一点main。我正在尝试,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;
4

1 回答 1

2

您的问题是您在最终INSERT语句中使用FROM tmp, stage;. 如果您在阶段表中有 10 行,这将生成 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为表生成新的 ID,使用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;
于 2021-10-28T06:58:44.377 回答