我最近被问到这个问题而且有点难过,所以我想问专家......
鉴于两张表A& B,我想返回A和B中不重叠的所有值。想想两个重叠的圆圈;我们如何返回不在重叠中心部分的所有数据?而且,我必须使用ANSI标准SQL而不是Oracle语法。
假设我们想要一切专属于A& B,我的回答是
select *
from A
cross join B
minus
(select a.common_column from a
intersect
select b.common_column)
这看起来是否正确,甚至是否接近?如果它是正确的,有更有效的方法吗?
BTW - 我的解决方案被彻底拒绝了......谢谢!
答案 0 :(得分:2)
鉴于表A和表B,您正在寻找(A U B) - (A& B)。换句话说,你需要一个联合B减去他们的交集。记住A和B必须是联合兼容的,才能使此查询正常工作。我愿意:
(select * from A
union
select * from B
)
minus
(select * from A
intersect
select * from B
)
答案 1 :(得分:1)
可能是全外连接?
select coalesce(A.col, B.col)
from A full outer join B on A.col = B.col
where A.col is null or B.col is null;
答案 2 :(得分:0)
要计算设定的对称差异,您可以使用MINUS
和UNION ALL
的组合:
select * from (
(select * from A
minus
select * from B)
union all
(select * from B
minus
select * from A)
)
答案 3 :(得分:0)
您需要从两个表中选择所有数据,除非它们重叠,然后将数据与union结合起来。提供的代码应该适用于您的示例。
SELECT *
FROM
(
SELECT * FROM Table1
EXCEPT SELECT * FROM Table2
)
UNION
SELECT *
FROM
(
SELECT * FROM Table2
EXCEPT SELECT * FROM Table1
)
希望这有帮助。
答案 4 :(得分:0)
您的查询被拒绝,因为它在语法上不正确:列数不同,并且会混淆cross join
和union all
。但是,我认为你有正确的想法来解决这个问题。
您可以轻松解决此问题:
(select *
from A
union all
select *
from B
) minus
(select *
from A
intersect
select *
from B
);
即,使用union all
组合所有内容,然后减去两个表中出现的行。
当然,如果只有一个ID,那么您可以使用带有join
的ID和其他操作。
答案 5 :(得分:0)
就像弗兰克施密特在此期间回答的那样:
这里包含一个数据示例:
WITH
table_a(name) AS (
SELECT 'From_A_1'
UNION ALL SELECT 'From_A_2'
UNION ALL SELECT 'From_A_3'
UNION ALL SELECT 'From_A_4'
UNION ALL SELECT 'From_A_5'
UNION ALL SELECT 'From_BOTH_6'
UNION ALL SELECT 'From_BOTH_7'
UNION ALL SELECT 'From_BOTH_8'
)
,
table_b(name) AS (
SELECT 'From_B_1'
UNION ALL SELECT 'From_B_2'
UNION ALL SELECT 'From_B_3'
UNION ALL SELECT 'From_B_4'
UNION ALL SELECT 'From_B_5'
UNION ALL SELECT 'From_BOTH_6'
UNION ALL SELECT 'From_BOTH_7'
UNION ALL SELECT 'From_BOTH_8'
)
(SELECT * FROM table_a EXCEPT SELECT * FROM table_b)
UNION ALL
(SELECT * FROM table_b EXCEPT SELECT * FROM table_a)
ORDER BY name
;
name
From_A_1
From_A_2
From_A_3
From_A_4
From_A_5
From_B_1
From_B_2
From_B_3
From_B_4
From_B_5