postgresql:将table1复制到table2和table3,但使用返回的table2值插入table3

时间:2018-01-22 22:59:10

标签: sql postgresql

我有三张桌子:

  

table1(id,name,foo)
  table2(id,name)
  table3(id,id2,name,foo,bar)

我想将table1中的数据复制到表2和表2中。 3,但table3.id2必须对应table2中的行。我想我需要用RETURNING命令做一些事情,但我没有成功。

WITH oldstuff AS (
    SELECT name, foo, 'some value' AS bar
    FROM table1
  ),
  newstuff AS (
    INSERT INTO table2 (name)
    SELECT name FROM oldstuff
    RETURNING id AS id2 /* but i also need oldstuff.name, oldstuff.foo,and oldstuff.bar */
  )
INSERT INTO table3 (id2, name, foo, bar)
SELECT * FROM newstuff; /* I cant just do a join here because the fields arent unique */

1 个答案:

答案 0 :(得分:1)

从概念上讲,你会这样做:

newstuff

根据您的说法,这并不能完全符合您的要求,因为 INSERT INTO table2 (name) SELECT DISTINCT name FROM oldstuff RETURNING *; 中没有唯一的名称。为原始表生成唯一ID或仅向其中插入唯一数据:

WITH oldstuff AS (
      SELECT name, foo, 'some value' AS bar
      FROM table1
     ),
     newstuff AS (
      INSERT INTO table2 (name)
          SELECT name
          FROM oldstuff
          RETURNING *
    )
INSERT INTO table3 (id2, name, foo, bar)
    SELECT ns.id, ns.name, os.foo, os.bar
    FROM (SELECT ns.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) as seqnum
          FROM newstuff ns
         ) ns JOIN
         (SELECT os.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) as seqnum
          FROM oldstuff os
         ) os
         on ns.name = os.name and ns.seqnum = os.seqnum;
嗯。嗯。 。 。可能有一种愚蠢的方式:

readvar

这将使用重复的名称,并且您在最终表格中只得到一个匹配。