这是解决这个问题的一种方法(也可能是最有效的方法)。主要部分是对结果执行UNION ALL
和GROUP 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
是否意味着'LABEL'是两个表中的主键(它不能是'NULL'并且它不能有在两个表中的重复)? – mathguy