任何人都可以解释为什么这些查询不一样?

时间:2010-02-04 15:12:37

标签: sql oracle query-optimization

我维护的查询如下:

select field_1, field_2
from source_table
minus
select field_1, field_2
from source_table
where status_code in (3, 600);

当我查看这个查询时,我立刻想到,“那是蹩脚的。为什么不使用'NOT IN'并删除MINUS业务。所以我重新写了它:

select field_1, field_2
from source_table
where status_code not in (3, 600);

为了仔细检查我的理智,我得到了每个查询的计数。令我惊讶的是,第一个查询返回了789,089条记录,第二条查询返回了1,518,450条记录!

我从几个角度看了这个,但无法弄清楚这两个查询是如何不同的。谁能解释一下发生了什么,或者为什么我今天早上都是白痴?

4 个答案:

答案 0 :(得分:9)

这些查询确实不同。 field_1field2不等于status_code 3和600. field_1可能是'A'而field_2可能是'B',所以你会是从第一个看起来像A, B的SELECT中删除记录。原始可能是获得正确结果的最佳方式。

编辑:为了让您更好地了解正在发生的事情,您可以通过执行子查询以类似于您编写查询的方式获得相同的结果:

select distinct field_1, field_2
from source_table
where (field_1, field_2) not in (
    select field_1, field_2
    from source_table
    where status_code in (3, 600)
);

答案 1 :(得分:4)

如果field_1和field_2的组合没有唯一约束,则第二个查询可能包含重复项,而第一个查询不包含重复项,因为“减号”会抑制它们。尝试使用'distinct'查询第二个查询,看看计数是否匹配。

答案 2 :(得分:4)

UNION,MINUS和INTERSECT运算符仅返回唯一值。如果您有两行具有相同的field_1和field_2,则第一个查询将计算一次,而第二个将计算两次:

SQL> insert into source_table values ('a', 'b', 10);

SQL> insert into source_table values ('a', 'b', 10);

SQL> select field_1, field_2
  2  from source_table
  3  minus
  4  select field_1, field_2
  5  from source_table
  6  where status_code in (3, 600);

FIELD_1    FIELD_2
---------- ----------
a          b

SQL> select field_1, field_2
  2  from source_table
  3  where status_code not in (3, 600);

FIELD_1    FIELD_2
---------- ----------
a          b
a          b

答案 3 :(得分:3)

如果您对field_1,field_2或两者都没有唯一约束,则Alison可能是正确的。考虑一下你有一张桌子: A B 3 A B 10

第一个查询将消除两行,第二个只消除一行。 或者,如果在status_code列中有NULL值,则可能会得到不同的结果,如果列中包含NULL值,则(A或不是A)在SQL中不起作用。