2017-06-02 82 views
0

我有2个表,我需要做一个表比较:比较表中的内容

TABLE A 
    LABEL 
    VALUE 

TABLE B 
    LABEL 
    VALUE 

基本上我想:

  • 记录在该值不匹配的标签等于
  • 记录在表A中没有的表B
  • 记录表B中没有的表A

有了这些信息,我可以记录我需要的适当的历史数据。它会告诉我值在哪里发生了变化,或者标签被添加或删除的位置......您可以说TABLE A是“新”数据集,TABLE B是“旧”数据集。所以我可以看到正在添加的内容,删除的内容以及更改的内容。

一直试图与联盟&减少,但没有运气。

喜欢的东西:

A LABEL A VALUE  B LABEL B VALUE 
    --------------------------------------- 
    XXX  5   XXX   3 
    YYY  2 
          ZZZ   4 
    WWW  7   WWW   8 

如果标签和值都是一样的,我不需要他们的结果集。

+0

是否意味着'LABEL'是两个表中的主键(它不能是'NULL'并且它不能有在两个表中的重复)? – mathguy

回答

1

这是解决这个问题的一种方法(也可能是最有效的方法)。主要部分是对结果执行UNION ALLGROUP BY的子查询,仅保留由单个行组成的组。 (具有两行的组是两个表中存在相同行的组)。此方法由Marco Stefanetti发明 - 首先在AskTom讨论板上讨论。这种方法的好处 - 比较常见的“对称差异”方法 - 是每个基表只读取一次,而不是两次。然后,为了将结果置于所需格式,我使用了一个PIVOT操作(自Oracle 11.1起可用);在早期版本的Oracle中,可以使用标准的聚合外部查询来完成相同的操作。

请注意,我修改了输入以显示VALUE列中的NULL的处理。

重要:此解决方案假定LABEL是两个表中的主键;如果不是这样,那么所要求的输出甚至是否有意义还不清楚。

with 
    table_a (label, value) as (
       select 'AAA', 3 from dual 
     union all select 'CCC', null from dual 
     union all select 'XXX', 5 from dual 
     union all select 'WWW', 7 from dual 
     union all select 'YYY', 2 from dual 
     union all select 'HHH', null from dual 
    ), 
    table_b (label, value) as (
       select 'ZZZ', 4 from dual 
     union all select 'AAA', 3 from dual 
     union all select 'HHH', null from dual 
     union all select 'WWW', 8 from dual 
     union all select 'XXX', 3 from dual 
     union all select 'CCC', 1 from dual 
    ) 
-- End of test data (NOT PART OF THE SOLUTION!) SQL query begins below this line. 
select a_label, a_value, b_label, b_value 
from (
     select max(source) as source, label as lbl, label, value 
     from  (
        select 'A' as source, label, value 
         from table_a 
        union all 
        select 'B' as source, label, value 
         from table_b 
       ) 
     group by label, value 
     having count(*) = 1 
     ) 
pivot (max(label) as label, max(value) as value for source in ('A' as a, 'B' as b)) 
; 

输出

A_LABEL A_VALUE B_LABEL B_VALUE 
------- ------- ------- ------- 
YYY   2   
CCC    CCC   1 
WWW   7 WWW   8 
        ZZZ   4 
XXX   5 XXX   3