sql - 对于表 A 中的每个现有行,在表 B 中插入 N 行
问题描述
我正在尝试使用 SQL 编写迁移脚本。我很容易覆盖 DDL 部分,但现在我必须迁移现有数据,如下所示:
迁移前:
表框
uuid | active_service_number | 其他 BOX 列... |
---|---|---|
2869c64f-8ecb-4296-8c3b-1c72b308d59f | 2 | ... |
迁移后:
表框
uuid | 其他 BOX 列... |
---|---|
2869c64f-8ecb-4296-8c3b-1c72b308d59f | ... |
表 BOX_SERVICE
uuid | 数字 | 状态 | box_uuid |
---|---|---|---|
6a33d57f-e02b-4d0a-b258-3cef0bb3dff7 | 0 | 不活跃 | 2869c64f-8ecb-4296-8c3b-1c72b308d59f |
... | 1 | 不活跃 | 2869c64f-8ecb-4296-8c3b-1c72b308d59f |
... | 2 | 积极的 | 2869c64f-8ecb-4296-8c3b-1c72b308d59f |
... | ... | ... | ... |
... | ñ | 不活跃 | 2869c64f-8ecb-4296-8c3b-1c72b308d59f |
把它们加起来
- 对于每个 BOX 行,我想准确地创建 N BOX_SERVICE 行,编号从 0 到 N。(N 是预先确定的固定数字)
- 只有一个 BOX_SERVICE 的状态应设置为 ACTIVE,即对应 BOX 的 active_service_number(上例中为 2)的状态。
我弄清楚了伪代码,但似乎无法将其转换为 SQL。我试图用一个请求,多个请求,游标来做到这一点。
这是我的 DDL 的样子:
CREATE TABLE BOX_SERVICE (uuid varchar(255) NOT NULL,
number int,
state varchar(255) DEFAULT 'INACTIVE',
box_uuid varchar(255),
PRIMARY KEY(uuid),
CONSTRAINT FK_BOX_BOX_SERVICE FOREIGN KEY (box_uuid)
REFERENCES BOX(uuid)
);
-- Migrate existing data
ALTER TABLE BOX DROP active_service_number
解决方案
generate_series()
您可以使用and生成行cross join
:
select <uuid function>,
gs.n as number,
(case when gs.n = b.active_service_number then 'ACTIVE' else 'INACTIVE' end),
b.uuid as box_uuid
from box b cross join
generate_series(0, n, 1) as gs(n);
您的 Postgres 版本仅通过扩展提供 UUID。使用用于生成 UUID 的第一列的任何方法。
推荐阅读
- javascript - JS 没有运行 do-while 循环
- java - 如何在 Java 中创建自定义注解,如 Spring @Value?
- flutter - 如何使用 Flutter 在 Android 设备的 SQLite 数据库中手动缓存 Firestore 数据?
- r - 如何获得列中每个组的 p 值?
- javascript - 如何使 Select2 与 Form KTRepeater 一起工作?
- linux - `container_memory_working_set_bytes` 指标和容器上的 OOM-killer 之间有什么关系?
- ruby-on-rails - 调用特定服务时如何在 ruby Geocoder 中存根调用
- python - 图像未在 tkinter 中加载
- javascript - 如何在 nextjs 中创建生产版本
- powershell - PowerShell Copy-Item 未创建子文件夹