Oracle减去和联合操作/优先顺序

时间:2017-08-29 15:47:30

标签: sql oracle

我正在协助:

How to find unmatched rows in oracle without using set operator and join & also Query the unmatched column names for an particular row

考虑以下尝试查找在一个集合中找到的所有记录而不是另一个集合。 (注意--x下面表示结果集中预期的记录)

  

Oracle Database 11g企业版11.2.0.4.0版 - 64位

With test1 (A,b,c) as (
SELECT 2001,  'abc',    'john' from dual union all--
SELECT 2008,  'cab',    'sam' from dual union all--x
SELECT 2002,  'qwe',    'mike' from dual union all--x
SELECT 2002,  'asd',    'samuel' from dual union all--
SELECT 2012,  'ddd',    'sammy' from dual),--x

test2 (a,b,c) as (
SELECT 2001, 'abc',    'john' from dual union all--
SELECT 2008, 'c@b',    'saam' from dual union all--x
SELECT 2009, 'qwe',    'mike' from dual union all--x
SELECT 2002, 'asd',    'samuel' from dual union all--
SELECT 2001, 'a bc',   'john' from dual ),--x

cte as (Select * from test1 minus Select * from test2),

cte2 as (Select * from test2 minus Select * from test1)

Select * from cte
union 
Select * from cte2;

导致预期结果:

+------+------+-------+
|  A   |    B |    C  |
+------+------+-------+
| 2001 | a bc | john  |
| 2002 | qwe  | mike  |
| 2008 | c@b  | saam  |
| 2008 | cab  | sam   |
| 2009 | qwe  | mike  |
| 2012 | ddd  | sammy |
+------+------+-------+

VS ......(为什么我们需要使用CTE?我们不能将所有两个查询联合起来吗?)

With test1 (A,b,c) as (
SELECT 2001,  'abc',    'john' from dual union all
SELECT 2008,  'cab',    'sam' from dual union all
SELECT 2002,  'qwe',    'mike' from dual union all
SELECT 2002,  'asd',    'samuel' from dual union all
SELECT 2012,  'ddd',    'sammy' from dual),

test2 (a,b,c) as (
SELECT 2001, 'abc',    'john' from dual union all
SELECT 2008, 'c@b',    'saam' from dual union all
SELECT 2009, 'qwe',    'mike' from dual union all
SELECT 2002, 'asd',    'samuel' from dual union all
SELECT 2001, 'a bc',   'john' from dual )

Select * from test1 minus select * from test2
union ALL
Select * from test2 minus select * from test1

这只是给了我们。

+------+------+------+
|  A   |    B |    C |
+------+------+------+
| 2001 | a bc | john |
| 2008 | c@b  | saam |
| 2009 | qwe  | mike |
+------+------+------+

显然不是......为什么? (注释表明如果我将()中的每个select包装为减去它的工作(并且它确实)必须在操作中具有相同的优先级。)所以这样做:

(Select * from test1 minus select * from test2)
union ALL
(Select * from test2 minus select * from test1)

我知道我可以在不同之后将两个集合结合起来然后进行计数......但是为什么反向minused集合的联合不起作用?这是一个错误(或者我找不到doc的功能吗?:P)[在评论中回答!]等待接受答案!

SELECT * 
FROM (SELECT Distinct * FROM test1 UNION ALL
      SELECT Distinct * FROM test2)
GROUP BY A,B,C
HAVING count(*) = 1

所以......我的查询是做什么的:

[等待有人发帖评论的答案!]

(Select * from test1 minus select * from test2 UNION ALL SELECT * FROM TEST2)
  MINUS select * from test1

而不是

(Select * from test1 minus select * from test2) 
UNION ALL 
(SELECT * FROM TEST2 MINUS select * from test1)

1 个答案:

答案 0 :(得分:2)

Select * from cte
union 
Select * from cte2

这里cteunion编辑,分别评估2个表上的minus操作。

然而,这个查询

Select * from test1 minus select * from test2
union ALL
Select * from test2 minus select * from test1

minusunion这些是设置运算符。所有集合运算符具有相同的优先级。因此,他们会逐一从leftright进行评估。

因此,这些查询的结果是不同的。要明确指定顺序,请在两个查询周围使用括号。

(Select * from test1 minus select * from test2)
union
(Select * from test2 minus select * from test1)

Documentation on set operators