sql - 使用 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)
解决方案
我相信 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;
推荐阅读
- php - Laravel - 通过作业类发送通知 - 将通知排队到 redis 队列而不发送两次
- c# - 如何在 image.source 中为 listView 的每个元素定期设置图像?
- java - Java - docx4j-ImportXHTML:找不到 NamespacePrefixMapper 的问题
- javascript - 为什么 map、every 和其他数组函数会跳过空值?
- azure - SocketException:试图以访问权限禁止的方式访问套接字
- ios - 在循环中填充字典值
- amazon-s3 - EMR JupyterHub:笔记本的 S3 持久性不工作
- angular - 在表单数组中添加和删除输入字段(反应式表单)
- c# - Hangfire - 多租户,ASP.NET Core - 解析正确的租户
- r - Databricks 上的 mgcv:k-index 的值与 RStudio 中的值不同