Sql 有人能解释一下为什么这些疑问是不一样的吗?

Sql 有人能解释一下为什么这些疑问是不一样的吗?,sql,oracle,query-optimization,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’并删除负号。所以我重新写了它: select field_1, field_2 from source_table where status_co

我一直在维护一个查询,如下所示:

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’并删除负号。所以我重新写了它:

select field_1, field_2
from source_table
where status_code not in (3, 600);
为了再次检查我的理智,我得到了每个查询的计数。令我惊讶的是,第一个查询返回789089条记录,第二个查询返回1518450条记录


我从多个角度看了这一点,但不知道这两个查询有什么不同。有人能解释发生了什么事,或者为什么我今天早上是个白痴吗?

这些查询确实不同。
field\u 1
field2
并不等同于
status\u code
3和600。
field\u 1
可以是“A”And
field_2
可以是“B”,因此您将从第一次选择中删除类似于
A,B
的记录。原始记录可能是获得正确结果的最佳方法

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

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)
);

如果您没有对Field1、FieldI2或两者都有一个独特的约束,艾丽森可能是正确的。 A B 3 A B 10

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

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

UNION、减号和INTERSECT运算符s仅返回唯一的值。如果有两行具有相同的字段_1和字段_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

你能发布两个查询的计划吗?啊,刚刚有一个小插曲。谢谢你的帮助!那还是不一样的。减号是一个set命令,会隐式执行一个distinct。你需要将它添加到替换项中。@Gary谢谢。我已经相应地更改了SQL。啊,那个细节有很大的不同。我忘记了。谢谢!你如果这是完整的故事,我们可以简单地插入DISTINCT并完成它。但是,正如上面的一些帖子所显示的,这不是完整的故事(当然是一个有效的观点)。