Select *
From (
Select a
Except
Select b
) x
UNION ALL
Select *
From (
Select b
Except
Select a
) y
此sql语句返回极其错误的数据量。如果Select a返回一百万,那么整个语句如何返回100,000?在这种情况下,选择b包含互斥数据,因此除了。之外不应该消除。
答案 0 :(得分:1)
正如评论中所述,EXCEPT根据 this 执行隐式DISTINCT,并且UNION ALL中的ALL无法重新创建重复项。因此,如果您想保留重复项,则无法使用您的方法。
由于您希望获取其中一个表a
和b
中包含的数据,而不是两者中的数据,因此更有效的方法是实现以下目标(我是假设表格中有id
和c
列,其中id
是主键,因为您没有说明任何列名称):
SELECT CASE WHEN a.id IS NULL THEN 'from b' ELSE 'from a' END as source_table
,coalesce(a.id, b.id) as id
,coalesce(a.c, b.c) as c
FROM a
FULL OUTER JOIN b ON a.id = b.id AND a.c = b.c -- use all columns of both tables here!
WHERE a.id IS NULL OR b.id IS NULL
这使用FULL OUTER JOIN
,通过WHERE条件排除匹配记录,因为主键不能为空,除非它来自OUTER
侧。
如果您的表没有主键 - 这仍然是不好的做法 - 您必须检查NULL
的所有列,而不仅仅是一个主键列。
如果您的记录完全由NULL
组成,则此方法不起作用。
然后你可以使用类似于原始方法的方法,只需使用
SELECT ...
FROM a
WHERE NOT EXISTS (SELECT 1 FROM b WHERE <join by all columns>)
UNION ALL
SELECT ...
FROM b
WHERE NOT EXISTS (SELECT 1 FROM a WHERE <join by all columns>)
答案 1 :(得分:0)
如果您尝试获取一个表中的任何数据而不是另一个表中的任何数据,我将尝试类似以下内容:
select id, 'table a data not in b' from a where id not in (select id from b)
union
select id, 'table b data not in a' from b where id not in (select id from a)