SQL 中的三向差异

时间:2021-01-18 05:45:15

标签: sql postgresql diff

我有三个 SQL 表(ABC),代表数据集的三个不同版本。我想设计一个 SQL 查询,其作用是提取在所有三个表中其值都不同的行/元组的 id。 (如果存在记录不共享相同值的字段,则两条记录不同。)为简单起见,我们假设ABC 每个都有{{ 1}} 条记录,其记录 id 范围从 1 到 N,因此对于从 1 到 N 的每个 id,每个表中都有一个具有该 ID 的记录。

在 SQL 中执行此操作的最有效方法是什么?一种方法是做类似的事情

N

基本上我在上面所做的是首先找到记录的 ID,其中 (SELECT id FROM ((SELECT * FROM A EXCEPT SELECT * FROM B) EXCEPT (SELECT * FROM C)) result) EXCEPT (SELECT id FROM ((SELECT * FROM A) INTERSECT (SELECT * FROM B)) result2) 中的版本与 A 的版本和 B 中的版本不同(在第一个我写的两行 SQL 查询)。剩下的就是过滤掉 C 中的版本与 B 中的版本匹配的记录 ID(在最后两行中完成)。但这似乎非常低效;有没有更好、更简洁的方法?

注意:我在这里使用的是 PostgreSQL 语法。

2 个答案:

答案 0 :(得分:2)

您可以按如下方式使用 group byhaving

select id from
(select * from A
union select * from B
union select * from C)
group by id
-- use characters that you know will not appear in this columns for concat
having count(distinct column1 || '#~#' || column2 || '#~#' || column3) = 3

答案 1 :(得分:2)

我会这样做:

select id, 
       a.id is null as "missing in a",
       b.id is null as "missing in b",
       c.id is null as "missing in c",
       a is distinct from b as "a and b different",
       a is distinct from c as "a and c different",
       b is distinct from c as "b and c different"
from a 
  full join b using (id)
  full join c using (id) 
where a is distinct from b
   or b is distinct from c
   or a is distinct from c   

id 列被假定为主键(或唯一键)。

Online example

相关问题