简体   繁体   中英

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

I am trying to write a migration script using SQL. I got the DDL part pretty easily covered, but now i have to migrate the existing data as shown below:

Before Migration:

Table BOX

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

After Migration:

Table BOX

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

To sum it up

  • For each BOX row, I want to create exactly N BOX_SERVICE rows , numbered from 0 to N. (N is a fixed number predetermined)
  • Only one BOX_SERVICE should have it's state set to ACTIVE, the one corresponding to active_service_number (2 in the example above) of the corresponding BOX.

I got the pseudo-code figured out, but can't seem to translate it into SQL. I tried to do it with a single request, with multiple requests, cursors.

Here is what my DDL is looking like:

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
               

You can generate the rows using 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);

Your version of Postgres only offers UUIDs via an extension. Use whatever method you use for the first column of generating UUIDs.

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

Output:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM