我可以从插入选项中返回未包含在插入内容中的字段吗?

时间:2016-10-13 20:32:27

标签: sql postgresql

使用Postgres 9.5。

我有一张表base,其中包含一些记录:

CREATE TABLE base
(
    id    serial NOT NULL
  , thing varchar
  , copy  varchar
);

我想将这些记录的子集插入表new

CREATE TABLE new
(
    id        serial NOT NULL
  , new_thing varchar
  , new_copy  varchar
);

new没有要存储base.id的列。但我希望能够从new.id映射到base行的new行:

CREATE TABLE base_to_new
(
    base_id int NOT NULL
  , new_id  int NOT NULL
);

这是我想要的要点,但它不起作用:

WITH new_rows AS
(
  INSERT INTO new
  (
    , new_thing
    , new_copy
  )

  SELECT
      thing
    , copy

  FROM base

  WHERE copy = 'yes'

  RETURNING
  (
      base.id AS base_id
    , new.id  AS new_id
  )
)

INSERT INTO base_to_new

SELECT
    new_rows.base_id
  , new_rows.new_id

FROM new_rows
;

basenew的架构不可更改。

我也想避免以下情况,因为实际上还有更多 字段比示例表中的表格非常大, 让我们成为现实,做一堆比较是蹩脚的。

INSERT INTO base_to_new

SELECT 
    base.id
  , new.id

FROM base

LEFT JOIN new
  ON  thing = new_thing
  AND item  = new_item 
  AND stuff = new_stuff
  AND last  = new_last
;

这是一个带有架构和一些数据的SQL小提琴:

http://sqlfiddle.com/#!15/bbb9d

谢谢!

1 个答案:

答案 0 :(得分:1)

这可以假设base.thing是唯一的:

with sel as (
    select *
    from base
    where copy = 'yes'
),
ins as (
    insert into new (new_thing, new_copy)
    select thing, copy
    from sel
    returning *
)
insert into base_to_new
select sel.id, ins.id
from sel
join ins on sel.thing = ins.new_thing;
不过,我不喜欢这个模型真的很麻烦。在base.id中存储new更简单,更自然。对于表名或列名,我也会避免使用newcopy这两个词,因为它们在Postgres中有其自己的含义。