【问题标题】:What is the difference between NOT condition and NOT() in Oracle and MS SQL ServerOracle 和 MS SQL Server 中的 NOT 条件和 NOT() 有什么区别
【发布时间】:2017-05-21 03:14:46
【问题描述】:

最近碰巧在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 中有类似的功能,但名称不同。
  • SQL 2014 和 2016:在 IN() 子句中使用文字参数列表,SQL 执行计划没有区别。如果涉及 PK 列,则为聚集索引查找,否则为聚集索引扫描。使用子查询和最佳键,它将是两次扫描和一个左反半连接,无论 NOT 运算符放在哪里都没有区别。

标签: sql sql-server oracle


【解决方案1】:

当您有 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 中,您的示例在 SQL Server 2014 和 SQL Server 2016 中的执行计划是相同的(假设:表有一个主键并且country 没有被索引)。

    有一个警告,尤其是您给出的示例:IN 运算符的行为与人们预期的不同,当它的参数中有 NULL 值时。对于甲骨文,see here;

    对于 T-SQL,请考虑:

    select 1 where 'A' in (null)
    

    这不会返回一行。这看起来微不足道,但是:

    select 1 where 'A' not in (null)
    

    这个语句也不会返回一行。现在我们可以争辩说,如果我们像这样从第一条语句逻辑反转表达式,它肯定应该返回一行:

    select 1 where not ('A' in (null))
    

    但事实并非如此,因为 IN (NULL) 的计算结果为 neither true nor false

    【讨论】:

      【解决方案3】:

      在你的情况下,没有真正的区别

      看看这个:

      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() 比将or 重写为and ... not ... 更容易

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-22
        • 1970-01-01
        • 2011-05-09
        • 2011-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多