首页 > 解决方案 > 对于表 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

把它们加起来

我弄清楚了伪代码,但似乎无法将其转换为 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
               

标签: sqlpostgresqlpostgresql-9.5

解决方案


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 的第一列的任何方法。


推荐阅读