我想找到两个select
语句中的所有行,其中行属于(所有列匹配) 选择语句但不是。
我知道如何在单一方向实现这一目标
select foo from foobar where bar = 1
minus
select foo from foobar where bar = 2;
这将返回第一个选择语句中foo存在的所有行,但不返回最后一个,但不是其他方式。
我知道我能做到
(select foo from foobar where bar = 1
minus
select foo from foobar where bar = 2)
union
(select foo from foobar where bar = 2
minus
select foo from foobar where bar = 1);
返回所需的结果。但这是很多重复。是否有一些像minus
这样的运算符可以同时运行?
另外,我想在结果中添加标识符,表示它属于哪个选择。但仅此一点就会使所有行都不同。
答案 0 :(得分:1)
SET运算符仅
UNION由查询
选择的所有不同行UNION ALL由任一查询选择的所有行,包括所有行 重复
INTERSECT两个查询选择的所有不同行
MINUS由第一个查询选择但不是第二个
选择的所有不同行
你可以使用交叉但是选择的数量是非常相同的
(select foo from foobar where bar = 1
union
select foo from foobar where bar = 2)
minus
(select foo from foobar where bar = 1
intesect
select foo from foobar where bar = 2)
答案 1 :(得分:1)
如果两个行集(无论是基表还是其他计算结果)已经重复数据删除,那么您可以使用
select foo
from (
select foo from rowset_1
union all
select foo from rowset_2
)
group by foo
having count(*) = 1
优点 - 特别是如果行集是基表 - 是每个只扫描一次,而不是每次扫描两次。
如果结果集未进行重复数据删除,您可以在两个地方select foo
更改select distinct foo
。
如果您可能在每个结果集中都有重复项,并且您还希望显示两个表共有的行(foo
值),但具有不同的多重性(例如,三个重复项),则会有类似的解决方案一行,但另一行有五个重复。)
答案 2 :(得分:1)
在这种情况下(总是相同的表),您可以简单地聚合:
select foo, max(bar)
from foobar
where bar in (1,2)
group by foo
having count(distinct bar) = 1;
这给你所有foo只有bar 1或bar 2而不是两者。 max(bar)
告诉你foo有两个值中的哪一个。