2014-09-25 52 views
1

我有兩個包含相同列的表。一個是我需要用作中間數據存儲器的臨時表,另一個是我的最終表。從臨時表中,只插入新表中不存在的行。 PostgreSQL

CREATE TABLE scratch_table (
    a text, 
    b text 
); 

CREATE TABLE final_table (
    a text, 
    b text 
); 

scratch_table有這三行:

a  | b 
-----------|------------ 
'text a 1' | 'text b 1' 
'text a 2' | 'text b 2' 
'text a 3' | 'text b 3' 

和final_table有兩行:

a  | b 
-----------|----------- 
'text a 1' | 'text b 1' 
'text a 4' | 'text b 4' 

我需要編寫一個查詢,需要在scratch_table所有行,並插入只有那些在final_table中不存在。在final_table年底應該是:

a  | b 
-----------|----------- 
'text a 1' | 'text b 1' 
'text a 2' | 'text b 2' 
'text a 3' | 'text b 3' 
'text a 4' | 'text b 4' 

只有該行'text a 4','text b 4'從scratch_table插入final_table,因爲它沒有存在過。

請不要指出我使用的數字(1-4)並不表示任何順序,我只是想區分每行的數據。謝謝!

+0

你有意在a和b列中配對嗎?只檢查一列就行嗎? – Miki 2014-09-25 22:19:55

回答

0

EXCEPT運算符是ANSI SQL。它需要兩組並僅返回第一組中不存在的行。

INSERT INTO final_table (a,b) 
SELECT a, b 
FROM scratch_table 

EXCEPT 

SELECT a, b 
FROM final_table 

EXCEPT運算符將只返回不同的行。如果您不想刪除重複項,請改爲使用EXCEPT ALL

0

有幾個方法可以做到這一點,利用not exists這裏:

insert into final_table 
select a, b 
from scratch_table st 
where not exists (
    select 1 
    from final_table ft 
    where ft.a = st.a and ft.b = st.b 
) 

這將插入從scratch_table不中final_table存在任何記錄,在ab領域都匹配。

+0

謝謝!現在,我的實際表格有13行。我只用了一行兩行的小桌子來說明我的情況。你給我的答案完美,但我需要很多AND(13!)。對不起,我以前沒有詳細說明。有沒有更清晰的方法來達到同樣的效果? – LuisC 2014-09-25 22:32:43

+0

@LuisC - 我不確定我是否理解?你爲什麼需要13個'和'子句? 'SELECT 1'並不意味着選擇第一行,它只是意味着選擇它是否匹配(你可以簡單地說'select *')。它應該適用於整個桌子。 – sgeddes 2014-09-26 00:47:43

+0

@LuisC - 順便說一句,這裏有一個很好的閱讀'except'和'not exists'之間的性能差異(以及其他一些方法)。 http://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join – sgeddes 2014-09-26 00:50:39