2016-10-13 43 views
1

使用Postgres 9.5。我可以從插入選擇中返回沒有包括在插入中的字段嗎?

我有一個表base一些記錄:

CREATE TABLE base 
(
    id serial NOT NULL 
    , thing varchar 
    , copy varchar 
); 

我想插入這些記錄的一個子集到表new

CREATE TABLE new 
(
    id  serial NOT NULL 
    , new_thing varchar 
    , new_copy varchar 
); 

new沒有一個列來存儲base.id。不過,我想能夠從new.id映射到base行的new行從創建:

CREATE TABLE base_to_new 
(
    base_id int NOT NULL 
    , new_id int NOT NULL 
); 

這是我想要的要點,但它不工作:

WITH new_rows AS 
(
    INSERT INTO new 
    (
    , new_thing 
    , new_copy 
) 

    SELECT 
     thing 
    , copy 

    FROM base 

    WHERE copy = 'yes' 

    RETURNING 
    (
     base.id AS base_id 
    , new.id AS new_id 
) 
) 

INSERT INTO base_to_new 

SELECT 
    new_rows.base_id 
    , new_rows.new_id 

FROM new_rows 
; 

basenew的架構不可更改。

我也想避免以下情況,因爲在現實中,還有更多的 字段比示例表中的表格非常大,並且讓我們成爲現實,做一堆比較是跛腳的。

INSERT INTO base_to_new 

SELECT 
    base.id 
    , new.id 

FROM base 

LEFT JOIN new 
    ON thing = new_thing 
    AND item = new_item 
    AND stuff = new_stuff 
    AND last = new_last 
; 

這裏是一個SQL擺弄着架構和一些數據:

http://sqlfiddle.com/#!15/bbb9d

謝謝!

回答

1

這工作假設base.thing是獨一無二的:

with sel as (
    select * 
    from base 
    where copy = 'yes' 
), 
ins as (
    insert into new (new_thing, new_copy) 
    select thing, copy 
    from sel 
    returning * 
) 
insert into base_to_new 
select sel.id, ins.id 
from sel 
join ins on sel.thing = ins.new_thing; 

順便說一句,我不喜歡這種型號爲真麻煩。在new中儲存base.id更簡單且更自然。對於表格或列名,我也避免使用newcopy這兩個詞,因爲它們在Postgres中有它們自己的含義。

+0

謝謝你的回答,但這並不能解決我的問題。如果你在最後看到我的註釋,那麼爲了確保base的行與插入new的行相同,我需要做的字段比較的數量太大了。另外,'new'中已經有了符合這些條件的行。我需要訪問insert中的'base.id'。 – Sibicle

+0

您正試圖解決在更好的設計中永遠不會出現的問題,請參閱我的答案中的說明。 – klin

+0

我們並不總是有與理想的設計工作的奢侈!有時我們正在使用具有數百列和數百萬行的表的傳統軟件,我們只需找到一個可行的解決方案。無論如何,謝謝! – Sibicle

相關問題