使用 SQL 的实体和关系的深层复制
Deep copy of entity and relationships using SQL
我有三个table
Store
Book
Page
store对书是一对多的,书对page是一对多的,它们都设置了外键。我想使用 SQL 查询创建商店的副本(以及相应的书籍和页面)。我试过使用 CTE,但我在维护实体之间的关系时遇到了问题。
我不是要创建一个新的 table,只是创建一个特定商店行(及其关系)的副本,table 上的 ID 是连续的。
所以一份
Store 1
Book 1 (store_id: 1)
Page 1 (book_id: 1)
Page 2 (book_id: 1)
会是
Store 2
Book 2 (store_id: 2)
Page 3 (book_id: 2)
Page 4 (book_id: 2)
我相信当 insert . . . select
有一个 order by
时,Postgres 将保留序列号的顺序。因此,您可以通过使用 returning
并从旧值和新值创建映射 table 来做您想做的事:
with s as (
insert into stores ( . . . )
select . . .
from stores
where store_id = @x
returning *
),
b as (
insert into books (store_id, . . . )
select s.store_id, . . .
from books b cross join
s
where b.store_id = @x
order by b.book_id
returning *
),
bb as (
select bold.book_id as old_book_id, bnew.book_id as new_book_id
from (select b.book_id,
row_number() over (order by book_id) as seqnum
from books b cross join
s
where b.store_id = @x
) bold join
(select b.*, row_number() over (order by book_id) as seqnum
from b
) bnew
on bnew.seqnum = bold.seqnum
)
insert into pages (book_id, . . .)
select bb.new_book_id, . . .
from pages p join
bb b
on p.book_id = bb.old_book_id;
我有三个table
Store
Book
Page
store对书是一对多的,书对page是一对多的,它们都设置了外键。我想使用 SQL 查询创建商店的副本(以及相应的书籍和页面)。我试过使用 CTE,但我在维护实体之间的关系时遇到了问题。
我不是要创建一个新的 table,只是创建一个特定商店行(及其关系)的副本,table 上的 ID 是连续的。
所以一份
Store 1
Book 1 (store_id: 1)
Page 1 (book_id: 1)
Page 2 (book_id: 1)
会是
Store 2
Book 2 (store_id: 2)
Page 3 (book_id: 2)
Page 4 (book_id: 2)
我相信当 insert . . . select
有一个 order by
时,Postgres 将保留序列号的顺序。因此,您可以通过使用 returning
并从旧值和新值创建映射 table 来做您想做的事:
with s as (
insert into stores ( . . . )
select . . .
from stores
where store_id = @x
returning *
),
b as (
insert into books (store_id, . . . )
select s.store_id, . . .
from books b cross join
s
where b.store_id = @x
order by b.book_id
returning *
),
bb as (
select bold.book_id as old_book_id, bnew.book_id as new_book_id
from (select b.book_id,
row_number() over (order by book_id) as seqnum
from books b cross join
s
where b.store_id = @x
) bold join
(select b.*, row_number() over (order by book_id) as seqnum
from b
) bnew
on bnew.seqnum = bold.seqnum
)
insert into pages (book_id, . . .)
select bb.new_book_id, . . .
from pages p join
bb b
on p.book_id = bb.old_book_id;