3

次の挿入を行うための最良の方法は何でしょうか。私は周りを見回しました、そして私はちょっと立ち往生しています。

私が現在持っているテーブル(挿入)

| id | order_id | item_id | type | group |
| 1  | 1        | 1       | 2    | 1     |  <- type 2 represents a "header" item, or a "kit"
| 2  | 1        | 2       | 1    | 1     |  <- type 1 represents a member of the "kit"
| 3  | 1        | 3       | 1    | 1     |
| 4  | 1        | 4       | 2    | 2     |  <- New group means new kit
| 5  | 1        | 2       | 1    | 2     |
| 6  | 1        | 5       | 1    | 2     |

これらの項目を次の 2 つのテーブルに挿入する必要があります
。1) item_entry

| id | mode | tmplt_id | item_id | parent_item_entry_id |
| 1  | 1    | 1        | NULL    | NULL                 | <- This is a header line, mode 1
| 2  | 2    | NULL     | 2       | 1                    | <- This is a sub line, mode 2
| 3  | 2    | NULL     | 3       | 1                    | <- parent_item_entry_id references the header it belongs to
| 4  | 1    | 4        | NULL    | NULL                 |
| 5  | 2    | NULL     | 2       | 4                    |
| 6  | 2    | NULL     | 5       | 4                    |

2) item_entry_details

| id | item_entry_id | order_id | group |
| 1  | 1             | 1        | 1     | 
| 2  | 4             | 1        | 2     | <- only header information is necessary

もちろん、item_entry.id はシーケンス (item_entry_id_seq) から駆動されます。これを機能させるためのエレガントな方法はありますか?現在、各グループをループして、最初に nextval() を変数に割り当ててから、グループ内の各項目をループして、テーブルに書き込みます。

FOR recGroup IN SELECT DISTINCT group FROM insert LOOP
  intParentItemEntryID := nextval('item_entry_id_seq');
  FOR recLine IN SELECT * FROM insert LOOP
    INSERT INTO item_entry VALUES (CASE intParentItemEntryID/DEFAULT, CASE 1/2, CASE recLine.item_id/NULL, CASE NULL/recLine.item_id, CASE NULL/intParentItemEntryID)
    INSERT INTO item_entry_details VALUES (DEFAULT, intParentItemEntryID, recLine.order_id, recLine.group);
  END LOOP;
END LOOP;

より良い方法はありますか、またはこのタイプの挿入を行うことができる唯一の方法は上記ですか?

4

1 に答える 1

4

ここでは「行単位」の手続き型コードは必要ありません。単純な古い SQL で十分です。

-- create the tables that the OP did not provide
DROP TABLE the_input;
CREATE TABLE the_input
    ( id INTEGER NOT NULL PRIMARY KEY
    , order_id INTEGER NOT NULL
    , item_id INTEGER NOT NULL
    , ztype INTEGER NOT NULL
    , zgroup INTEGER NOT NULL
    );
DROP TABLE target1 ;
CREATE TABLE target1
    ( id INTEGER NOT NULL  
    , zmode INTEGER NOT NULL 
    , tmplt_id INTEGER     
    , item_id INTEGER      
    , parent_item_entry_id INTEGER  
    );
DROP TABLE target2 ;
CREATE TABLE target2
    ( id SERIAL NOT NULL   
    , item_entry_id INTEGER NOT NULL
    , order_id INTEGER NOT NULL   
    , zgroup INTEGER NOT NULL
    );

 -- fil it up ...
INSERT INTO the_input      
 ( id, order_id, item_id, ztype, zgroup ) VALUES
 ( 1  , 1        , 1       , 2    , 1     ) --  <- type 2 represents a "header" item, or a "kit"
,( 2  , 1        , 2       , 1    , 1     ) --  <- type 1 represents a member of the "kit"
,( 3  , 1        , 3       , 1    , 1     ) --
,( 4  , 1        , 4       , 2    , 2     ) --  <- New group means new kit
,( 5  , 1        , 2       , 1    , 2     ) --
,( 6  , 1        , 5       , 1    , 2     ) --
    ;

-- Do the inserts.
INSERT INTO target1(id,zmode,tmplt_id,item_id,parent_item_entry_id)
SELECT i1.id, 1, i1.id, NULL, NULL
FROM the_input i1
WHERE i1.ztype=2
UNION ALL
SELECT i2.id, 2, NULL, i2.id, ip.item_id
FROM the_input i2
JOIN the_input ip ON ip.zgroup = i2.zgroup AND ip.ztype=2
WHERE i2.ztype=1
    ; 
INSERT INTO target2(item_entry_id,order_id,zgroup)
SELECT DISTINCT MIN(item_id),order_id,  zgroup
FROM the_input i1
WHERE i1.ztype=2
GROUP BY order_id,zgroup
    ;
SELECT * FROM target1
ORDER BY id;

SELECT * FROM target2
ORDER BY id;

結果:

NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "the_input_pkey" for table "the_input"
CREATE TABLE
INSERT 0 6
DROP TABLE
CREATE TABLE
INSERT 0 6
 id | zmode | tmplt_id | item_id | parent_item_entry_id 
----+-------+----------+---------+----------------------
  1 |     1 |        1 |         |                     
  2 |     2 |          |       2 |                    1
  3 |     2 |          |       3 |                    1
  4 |     1 |        4 |         |                     
  5 |     2 |          |       5 |                    4
  6 |     2 |          |       6 |                    4
(6 rows)

DROP TABLE
NOTICE:  CREATE TABLE will create implicit sequence "target2_id_seq" for serial column "target2.id"
CREATE TABLE
INSERT 0 2
 id | item_entry_id | order_id | zgroup 
----+---------------+----------+--------
  1 |             4 |        1 |      2
  2 |             1 |        1 |      1
(2 rows)
于 2012-05-30T11:30:58.077 に答える