2015-02-09 53 views
2

我想插入多個(2)行到Postgres的表中,並使用WITH ROWS AS返回的ID插入到另一個表(列id_1和​​second_table),並返回 id作爲查詢的最終結果。Postgres從表中插入多個返回值作爲

first_table是主要數據收集,而second_table基本上只是將兩個first_table條目鏈接在一起。

這裏是我想要做的要點:

WITH row AS (
     INSERT INTO first_table (some_data, more_data) 
     VALUES (DEFAULT, DEFAULT), (DEFAULT, DEFAULT) 
     RETURNING first_table_id 
     ) 
INSERT INTO second_table (id_1, id_2, other_data) 
VALUES (???, ???, DEFAULT) 
RETURNING second_table_id 

我如何使用Node.js和node-pg模塊;我知道這可以在Node.js中完成,方法是讓第一個查詢返回WITH ROWS AS返回的兩行,然後使用下一個插入的兩個ID運行另一個準備好的語句。

我不確定我是否可以通過觸發器來執行此操作,因爲ON INSERT只有一行。也許它會有兩個,因爲這些行在同一個事務中插入到first_table中,但是我一般沒有豐富的Postgres/SQL經驗,所以我不知道如何通過觸發器來做到這一點。

我遇到的問題是,WITH ROWS AS語句返回2行(顯然是打算),但我不知道如何在下一個插入中獨立訪問每行,並且我感覺它不是不可能。

可這在單個查詢來完成,還是我用於此觸發器或Node.js的?

回答

3

第二次插入需要是INSERT INTO ... SELECT ... FROM first_cte。如果你可以做出一個假設,那第二個生成的id比第一個(或者至少是不同的 - 比如 - 如果你使用PostgreSQL的serial,或者直接使用一個序列)大,你可以使用聚合:

WITH rows AS (
    INSERT INTO first_table (some_data, more_data) 
    VALUES (DEFAULT, DEFAULT), (DEFAULT, DEFAULT) 
    RETURNING first_table_id 
) 
INSERT INTO second_table (id_1, id_2) 
SELECT min(first_table_id), max(first_table_id) 
FROM rows 
RETURNING second_table_id 

需要注意的是,省略other_data:你不能在INSERT INTO ... SELECT ...使用DEFAULT

對於更廣泛的解決方案,你可以使用數組:

WITH rows AS (
    INSERT INTO first_table (some_data, more_data) 
    VALUES (DEFAULT, DEFAULT), (DEFAULT, DEFAULT) 
    RETURNING first_table_id 
) 
INSERT INTO second_table (id_1, id_2, other_data) 
SELECT first_table_ids[1], first_table_ids[2], 5 -- value '5' for "other_data" 
FROM (
    SELECT array_agg(first_table_id) AS first_table_ids 
    FROM rows 
) AS rows_as_array 
RETURNING second_table_id 
+0

嘿pozs,這正是我一直在尋找!但是,是否可以在第二個INSERT(而不是'DEFAULT')中包含其他值?例如,我想這樣做:'INSERT INTO translations(source_id,destination_id,other_data)SELECT min(phrase_id),max(phrase_id)FROM rows,5',其中'other_data'具有實際值(此處爲'5' )。儘管獲取語法錯誤。這是否有正確的語法? – 2015-02-09 16:29:57

+0

@ChrisCirefice是的,你只需要在select中包含它作爲一個常量列,看看我的編輯。 – pozs 2015-02-09 16:30:44

+0

這絕對是完美的,正是我昨晚花了兩個小時試圖找出正確的語法!謝謝:)我確實使用'serial'作爲第一個表的列名,所以'min' /'max'解決方案簡單得多,符合我的用例。由於在SO上沒有類似的問題(無論如何我都能找到),所以我希望你能得到很多讚揚:)再次感謝! – 2015-02-09 16:33:20