我有一个查询,可以从单个表中检索数据。但是查询使用MINUS子句,如下所示:

SELECT field1, field2
FROM tab
WHERE field3 = 'a'
AND field4 = 'b'
    MINUS
SELECT field1, field2
FROM tab
WHERE field5 = 'c'
AND field6 = 'd'

由于这是从同一张表中选择的,因此我尝试重写此表以摆脱MINUS子句。我认为这样的事情应该起作用:
SELECT DISTINCT field1, field2
FROM tab
WHERE field3 = 'a'
AND field4 = 'b'
AND NOT (field5 = 'c'
AND field6 = 'd')

我的理由是,如果MINUS子句在第二个查询中排除了记录,那么将WHERE子句包装在AND NOT中应该摆脱相同的记录。 MINUS子句还消除了重复项,这就是为什么我在选择中添加了DISTINCT的原因。但是问题是我的查询返回的记录多于原始记录。

我在这里想念什么?

最佳答案

考虑以下两行:

1,2,a,b,x,y

1,2,u,v,c,d

MINUS操作不会返回该对(1、2),但您的查询将返回。 c,d值可能显示为相同的1、2,但与a,b处于不同的行

根本的区别在于MINUS在设置级别上运行,而您的NOT条件一次只能在一行上运行(同一行的其他列中都带有“required”值)。

现在:您可以使查询效率更高(尽管您无法避免两次读取基表)。使用NOT IN条件:

select field1, field2 from tab where field3 = 'a' and field4 = 'b'
and    (field1, field2) not in
           (select field1, field2 from tab where field5 = 'c' and field6 = 'd');

注意(请参见下面的spencer7593的注释):与所有可能存在NULL的情况一样,NOT IN不是一个好的解决方案。而是应使用NOT EXISTS条件。我不会详细说明,因为它似乎超出了所提问题的范围(这就是为什么“NOT”解决方案不同于“MINUS”解决方案的原因)。

09-25 22:21