2012-05-30 1 views
3

Что было бы лучшим способом сделать следующую вставку. Я огляделся, и я застрял.Pl/PgSQL, вставить в две таблицы, одну с заголовками строк

Таблица I В настоящее время есть (вставка)

| 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  | 

мне нужно вставить эти элементы в следующих двух таблицах:
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 управляется f последовательности (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

Нет необходимости в процедурный код «row-at-time» здесь, достаточно простого старого 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) 
+0

Спасибо за помощь! Я знал, что должен быть способ, я просто не мог понять. – BedderDanu

 Смежные вопросы

  • Нет связанных вопросов^_^