首页 > 解决方案 > 使用 SQL 深度复制实体和关系

问题描述

我有三张桌子

Store
  Book
    Page

商店与书籍是一对多的,书籍与页面是一对多的,它们都设置了外键。我想使用 SQL 查询创建商店的副本(以及相应的书籍和页面)。我尝试过使用 CTE,但在维护实体之间的关系时遇到了麻烦。

我不是想创建一个新表,只是创建特定 Store 行(及其关系)的副本,表上的 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)

标签: sqlpostgresqldeep-copy

解决方案


我相信 Postgres 会在 aninsert . . . select具有order by. returning因此,您可以通过使用并从旧值和新值创建映射表来做您想做的事情:

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;

推荐阅读