对于 table A 中的每个现有行,在 table B 中插入 N 行

For each existing row in table A, insert N rows in table B

我正在尝试使用 SQL 编写迁移脚本。 我很容易涵盖 DDL 部分,但现在我必须迁移现有数据,如下所示:

迁移前:

Table 盒子

uuid active_service_number other BOX columns...
2869c64f-8ecb-4296-8c3b-1c72b308d59f 2 ...

迁移后:

Table 盒子

uuid other BOX columns...
2869c64f-8ecb-4296-8c3b-1c72b308d59f ...

Table BOX_SERVICE

uuid number state box_uuid
6a33d57f-e02b-4d0a-b258-3cef0bb3dff7 0 INACTIVE 2869c64f-8ecb-4296-8c3b-1c72b308d59f
... 1 INACTIVE 2869c64f-8ecb-4296-8c3b-1c72b308d59f
... 2 ACTIVE 2869c64f-8ecb-4296-8c3b-1c72b308d59f
... ... ... ...
... N INACTIVE 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
               

您可以使用 generate_series()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 的第一列的任何方法。

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

select uuid_generate_v1(),sequence number,
(case when active_service_number=SEQUENCE    THEN 'ACTIVE' ELSE 'INACTIVE' END)STATE,
UUID BOX_UUID from box CROSS  JOIN (select generate_series(0,5) as sequence)t

输出:

UUID                                |Number|Status  |Box_UUID
4b247576-8e42-11eb-80ae-1831bf6eced8|0     |INACTIVE|2869c64f-8ecb-4296-8c3b-1c72b308d59f
4b247577-8e42-11eb-80af-1831bf6eced8|1     |INACTIVE|2869c64f-8ecb-4296-8c3b-1c72b308d59f
4b247578-8e42-11eb-80b0-1831bf6eced8|2     |ACTIVE  |2869c64f-8ecb-4296-8c3b-1c72b308d59f
4b247579-8e42-11eb-80b1-1831bf6eced8|3     |INACTIVE|2869c64f-8ecb-4296-8c3b-1c72b308d59f
4b24757a-8e42-11eb-80b2-1831bf6eced8|4     |INACTIVE|2869c64f-8ecb-4296-8c3b-1c72b308d59f
4b24757b-8e42-11eb-80b3-1831bf6eced8|5     |INACTIVE|2869c64f-8ecb-4296-8c3b-1c72b308d59f