I have three tables:
table1(id, name, foo)
table2(id, name)
table3(id, id2, name, foo, bar)
And I'd like to copy data from table1 to tables 2 & 3, but table3.id2 has to correspond to the row in table2. I think I need to do something with the RETURNING command, but I have been unsuccessful.
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 */
Conceptually, you would do:
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 newstuff ns join
oldstuff os
on ns.name = os.name;
From what you say, this doesn't do exactly what you want because there is not a unique name in newstuff
. Either generate a unique id for the original table or only insert unique data into it:
INSERT INTO table2 (name)
SELECT DISTINCT name
FROM oldstuff
RETURNING *;
Hmmm . . . There might be a kludgy way:
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;
This will work with duplicate names, and you get exactly one match in the final table.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.