Reputation: 825
I have a table
monster(id serial, name varchar, primary key(id))
and i have another table
ranged_monster(id_monster integer, distance integer, foreign key(id_monster) references monster)
I want to insert two ranged monsters: one is called 'archer goblin' with a range attack distance of 10, and the another is called 'dragon' with a range attack distance of 50. How can i do this in one instruction?
so far, i have tried this:
the worst way
insert into monster(name) values ('archer goblin'), ('dragon');
insert into ranged_monster(distance) values (10) where name='archer goblin';
insert into ranged_monster(distance) values (50) where name='dragon';
it is bad because the name column allows repetitions, and the retrieved records might be more than one... also having to write the name of the monster twice does not seems like a good habit.
insert into ... returning
if the table ranged_monster
only had the column (foreign key) of the id_monster
, then i could use this solution:
with the_ids as (
insert into monster(name)
values ('archer goblin'), ('dragon')
returning id
)
insert into ranged_monster(id_monster)
select * from the_ids;
however it does not work, because ranged_monster also has the column distance
. Doing so, will insert the ids of the monsters without distance
.
possible solutions
create a temporal table with the distances, and then combine this temporal table sequentially with the insert into ... returning
's the_ids
, and then insert this combined records into the ranged_monster
table.
How can i combine two tables as asked in here https://stackoverflow.com/questions/31171253/sql-combine-two-tables ? (it was marked as duplicated, linking to this What is the difference between JOIN and UNION? , but that question is not related to that another question.)
Upvotes: 2
Views: 660
Reputation: 125254
with s(name, distance) as (
values ('archer goblin', 10), ('dragon', 50)
), the_ids as (
insert into monster(name)
select name
from s
returning id, name
)
insert into ranged_monster (id_monster, distance)
select id, distance
from
s
inner join
the_ids using (name)
Upvotes: 1