2014-09-25 56 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