如何在PostgreSQL中比较两个表?

9

我有两个相同的表:

A :   id1, id2, qty, unit
B:    id1, id2, qty, unit

(id1,id2) 这个组合用于标识每一行数据,每个表中只能出现一次。

A 中有 140 行数据,表 B 中有 141 行数据。我想找到在两个表中都没有出现的所有键 (id1,id2)。至少有一个这样的键,但不能有多个(例如如果每个表中的数据完全不同)。

我编写了以下查询语句:

(TABLE a EXCEPT TABLE b)
UNION ALL
(TABLE b EXCEPT TABLE a) ;

但是它没有起作用。它比较整个表格,而我并不关心 qtyunit 是否不同,我只关心 id1,id2

2个回答

16

使用全外连接:

 select a.*,b.* 
 from a full outer join b 
   on a.id1=b.id1 and a.id2=b.id2

这将两个表格并排显示,未匹配的行之间会有间隔。

 select a.*,b.* 
 from a full outer join b 
   on a.id1=b.id1 and a.id2=b.id2
   where a.id1 is null or b.id1 is null;

它只会显示不匹配的行。

或者你可以使用 not in。

select * from a 
  where (id1,id2) not in
   ( select id1,id2 from b )

这将显示来自不被B匹配的行。

或者使用连接获得相同结果。

select a.* 
  from a left outer join b 
  on a.id1=b.id1 and a.id2=b.id2
  where b.id1 is null

有时候使用连接操作比使用“not in”更快。


如果行出现在B中而不在A中怎么办?第二个查询中NULL的目的是什么? - java
从两个表中获取第一个和第二个列表的结果,从表A中仅获取后两个列表,可以使用联合来包含补充查询以列出来自表B的结果。 "is null"排除包含两个表中记录的行。 - Jasen
1
如果两个表中存在相同的行,但某些列具有不同的值,该怎么办? - Paweł Sopel
1
原问题仅考虑id1、id2作为两个表的主键。 - Jasen
1
@PawełSopel 如果你想比较整行,请使用 a=b 而不是 a.id=b.id,但是在使用 EXCEPT 时可能会有更好的选择。 - Jasen

4

以下是使用EXCEPT查看记录差异的示例。将选择语句反转以查看不同之处。a except s / then s except a

SELECT
a.address_entrytype,
a.address_street,
a.address_city,
a.address_state,
a.address_postal_code,
a.company_id


FROM
prospects.address a  

except 

SELECT
s.address_entrytype,
s.address_street,
s.address_city,
s.address_state,
s.address_postal_code,
s.company_id

FROM
prospects.address_short s  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接