Oracle和MS SQL Server中NOT条件和NOT()之间的区别是什么?

7

最近我偶然发现了在Sql Server和Oracle中使用not()的情况。尝试了不同的例子,将NOT条件和not()与不同的操作符(如LIKE、IN等)进行比较。就结果集和记录数而言,我没有看到任何区别,但希望向社区确认这两者是否相同或存在任何注意事项?

查询示例:

select count(*) from Emp where country not in ('ENGLAND UK', 'HAITI', 'IRELAND') 
select count(*) from Emp where not(country  in ('ENGLAND UK', 'HAITI', 'IRELAND')) 

在SQL Server中,您可以让服务器生成执行计划。然后,您可以比较这两个查询的执行计划,并看到它们是相同的。在Oracle中也有类似的功能,只是名称不同。 - Damien_The_Unbeliever
SQL 2014和2016:在IN()子句中使用文字参数列表时,SQL执行计划没有区别。如果涉及PK列,则为聚集索引查找,否则为聚集索引扫描。使用子查询和最佳键时,将进行两次扫描和左反半连接,在NOT运算符放置的位置无论如何都没有区别。 - Cee McSharpface
3个回答

4

当您使用 AND/OR 与其他条件一起使用时,会产生不同的结果。它将把 AND 变为 OR,将 OR 变为 AND

select 1 where not(1 = 1 or 1 <> 1 )

将与之前相同

select 1 where (1 <> 1 and 1 = 1 )

并且

select 1 where not(1 = 1 and 1 <> 1 )

将会与之前相同

select 1 where (1 <> 1 or 1 = 1 )

并且。
select 1 where not(1 = 1) or 1 = 1 

不会与之前的内容相同。
select 1 where not(1 = 1 or 1 = 1 )

2
两个 NOT 关键字的使用在逻辑上等效,会得到相同的结果。在括号内的表达式之前添加 NOT 将反转该表达式的结果,但这是常规布尔逻辑,而不是特定于 SQL。
在 T-SQL 中,对于您的示例(假设表具有主键且未对 country 进行索引),SQL Server 2014 和 SQL Server 2016 的执行计划相同。
这里有一个特殊情况,尤其是在您给出的示例中:当 IN 运算符在其参数中具有 NULL 值时,它的行为与人们期望的不同。对于 Oracle,请参见这里;对于 T-SQL,请考虑以下内容:
select 1 where 'A' in (null)

这将不返回任何行。虽然看起来很琐碎,但是:
select 1 where 'A' not in (null)

这个语句也不会返回任何行。现在我们可以争论,如果我们将第一个语句的表达式逻辑取反,那么它肯定会返回一行:
select 1 where not ('A' in (null))

但它并没有,因为IN(NULL)的评估结果是既不是真也不是假

1
在您的情况下,没有真正的区别。
不过,请看这个例子:
where x1 not in ('a','b','c') 
and x2 not in ('x','y','z')

这可以写成:

这可以写成

where not (x1 in ('a','b','c')
           or x2 in ('x','y','z'))

在编写查询时,有时我会使用or来标识我想要排除的内容。使用not()比重写orand ... not ...更容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接