[英]Issues with SQL Select utilizing Except and UNION All
Select *
From (
Select a
Except
Select b
) x
UNION ALL
Select *
From (
Select b
Except
Select a
) y
此sql语句返回的数据量非常错误。 如果Select a返回一百万,那么整个语句如何返回100,000? 在这种情况下,Select b包含互斥数据,因此不应由于排除而消除。
正如评论已经指出,除非执行一个隐含的DISTINCT,根据本和都在你的UNION 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>)
如果您试图获取一个表中而不是另一个表中的任何数据,而不管是哪个表,那么我将尝试以下操作:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.