我有两张桌子,我需要做一个比较表:
TABLE A
LABEL
VALUE
TABLE B
LABEL
VALUE
基本上我想要:
有了这些信息,我可以记录我需要的正确历史数据。它会显示值的变化位置,或者添加或删除标签的位置......您可以说表A是"新的"数据集,表B是" old"数据集。所以我可以看到正在添加的内容,删除的内容以及更改的内容。
尝试使用UNION&没有,但还没有运气。
类似的东西:
A LABEL A VALUE B LABEL B VALUE
---------------------------------------
XXX 5 XXX 3
YYY 2
ZZZ 4
WWW 7 WWW 8
如果标签和值相同,我在结果集中不需要它们。
答案 0 :(得分:1)
这是解决此问题的一种方式(也许是最有效的方法)。主要部分是对结果执行UNION ALL
和GROUP 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