比较表格内容

时间:2017-06-02 20:58:10

标签: oracle compare union

我有两张桌子,我需要做一个比较表:

TABLE A
  LABEL
  VALUE

TABLE B
  LABEL
  VALUE

基本上我想要:

  • 记录匹配标签上值不相等的内容
  • 表A中不在表B中的记录
  • 表B中不在表A中的记录

有了这些信息,我可以记录我需要的正确历史数据。它会显示值的变化位置,或者添加或删除标签的位置......您可以说表A是"新的"数据集,表B是" old"数据集。所以我可以看到正在添加的内容,删除的内容以及更改的内容。

尝试使用UNION&没有,但还没有运气。

类似的东西:

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

如果标签和值相同,我在结果集中不需要它们。

1 个答案:

答案 0 :(得分:1)

这是解决此问题的一种方式(也许是最有效的方法)。主要部分是对结果执行UNION ALLGROUP BY的子查询,仅保留由单行组成的组。 (具有两行的组是两个表中存在相同行的组。)此方法由Marco Stefanetti发明 - 首先在AskTom讨论板上讨论。这种方法的好处 - 通过更常见的“对称差异”方法 - 每个基表只读取一次,而不是两次。

然后,为了将结果放在所需的格式中,我使用PIVOT操作(自Oracle 11.1起可用);在早期版本的Oracle中,可以使用标准聚合外部查询来完成相同的操作。

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

重要:此解决方案假设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