2017-06-22 56 views
1

我想找到两个select报表时,该行属于所有行(所有列匹配),以要么 SELECT语句,但不能同时甲骨文MINUS两种方式(获取选择之间的差值)

我知道如何在一个方向

select foo from foobar where bar = 1 
minus 
    select foo from foobar where bar = 2; 

这将返回所有行其中,foo是存在于第一个SELECT语句,但不是最后一个,但不是其他方式做到这一点英寸

我知道我可以做

(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

纠正我,如果我错了,但不会记录哪个'bar = 1'隐式不同于'bar = 2'(或任何其他值)的记录?也许你应该更新一个更好的例子。 –

+0

我没有返回所有列,而只是一个特定的列,这可能是通用的或不同的,不管酒吧 –

+0

如果您向我们显示一些实际样本数据,可能对其他人有帮助。一张图片胜过千言万语绝对适用于Stack Overflow的SQL查询问题。 –

回答

1

集合运算符是唯一

UNION由任一查询中选择由任一查询中所选择

UNION ALL的所有行,包括所有 所有不同的行复制

INTERSECT通过已选择所有不同的行两个查询

减去第一个查询选择的所有不同行,但不是第二个查询

你可以使用相交但选择的数量pratically相同

(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

如果两个行集(无论是基表或其他计算的结果)已经去重复的,那么你就可以使用

select foo 
from (
     select foo from rowset_1 
     union all 
     select foo from rowset_2 
    ) 
group by foo 
having count(*) = 1 

好处 - 特别是如果行集是基表 - - 是每个只扫描一次,而不是每个两次。

如果结果集尚未被重复删除,您可以在两个地方更改select fooselect distinct foo

如果在每个结果集中可能有重复项,并且您还想显示两个表共有的行(foo值),但是具有不同的多重性(例如,一个行集中有三个重复项但其他五个重复)。

1

在此情况下(总是相同的表),你可以简单地汇总:

select foo, max(bar) 
from foobar 
where bar in (1,2) 
group by foo 
having count(distinct bar) = 1; 

这使您只有要么棒1或2条,而不是所有的都富。 max(bar)告诉你foo具有哪两个值。