比较表内容



我有 2 个表,我需要做一个表比较:

TABLE A
LABEL
VALUE
TABLE B
LABEL
VALUE

基本上我想要:

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

有了这些信息,我就可以记录我需要的适当历史数据。 它将向我显示值已更改的位置,或者添加或删除标签的位置......您可以说表 A 是"新"数据集,表 B 是"旧"数据集。 因此,我可以看到正在添加的内容,已删除的内容以及更改的内容。

一直在尝试使用UNION和MINUS,但还没有运气。

像这样:

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

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

这是解决此问题的一种方法(也可能是最有效的方法)。主要部分是对结果执行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

相关内容

  • 没有找到相关文章

最新更新