SQL 中的 NOT 和 != 运算符有啥区别?
Posted
技术标签:
【中文标题】SQL 中的 NOT 和 != 运算符有啥区别?【英文标题】:What is the difference between NOT and != operators in SQL?SQL 中的 NOT 和 != 运算符有什么区别? 【发布时间】:2017-05-06 05:52:35 【问题描述】:SQL 中的NOT
和!=
运算符有什么区别?我无法理解其中的区别。我猜他们是一样的。
【问题讨论】:
Should I use != or <> for not equal in TSQL?的可能重复 【参考方案1】:NOT
否定以下条件,因此它可以与各种运算符一起使用。 !=
是 <>
运算符的 non-standard alternative,意思是“不相等”。
例如
NOT (a LIKE 'foo%')
NOT ( (a,b) OVERLAPS (x,y) )
NOT (a BETWEEN x AND y)
NOT (a IS NULL)
除了上面的overlaps
操作符还可以写成:
a NOT LIKE 'foo%'
a NOT BETWEEN x AND y
a IS NOT NULL
在某些情况下,否定一个完整的表达式可能更容易理解,而不是将其重写为相反的意思。
NOT
可以 但是可以与<>
一起使用——但这并没有多大意义:NOT (a <> b)
与a = b
相同。同样,您可以使用 NOT 来否定相等运算符 NOT (a = b)
与 a <> b
相同
【讨论】:
【参考方案2】:这个问题实际上比人们认为的要有意义得多。
首先,最初的 SQL 不等于运算符是 <>
,据我所知,后来才添加了 C 风格的 !=
。我个人总是使用<>
,因为!=
对我来说看起来很奇怪,但我是老派。
其次,最初的提问者当然不是要比较NOT
和!=
,而是比较NOT a = b
和a != b
之间的区别。直观上应该有所不同,但据我所知没有。
为了清楚起见,这里是一个在 PostgreSQL 上运行的示例会话(在 Oracle 中,您需要更多奇怪的东西,例如 SELECT ... FROM DUAL UNION ...
等,为了简洁起见,我避免使用这些东西):
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst;
a | b
---+---
1 | 2
2 | 3
4 |
(3 rows)
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst where b = 2;
a | b
---+---
1 | 2
(1 row)
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst where b != 2;
a | b
---+---
2 | 3
(1 row)
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst where not b = 2;
a | b
---+---
2 | 3
(1 row)
这里我们可能认为最后一个查询也应该返回行(4,NULL)。但它没有。在 PostgreSQL 中,我实际上可以进一步检查,如下所示:
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select *, b = 2 as beq2 from tst;
a | b | beq2
---+---+------
1 | 2 | t
2 | 3 | f
4 | |
(3 rows)
对于b
为NULL 的情况,您会看到布尔表达式b = 2 为NULL。但是,当布尔表达式为 NULL 时,它被视为 false,或者更确切地说 not true。当你用NOT
否定它时,表达式的布尔值保持为NULL,因此仍然不正确。
不幸的是,我只知道明确处理 NULL 情况,所以我必须写:
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst where b is null or b = 2;
a | b
---+---
1 | 2
4 |
(2 rows)
因此,您必须始终编写 a IS NULL OR b IS NULL OR ... OR z IS NULL OR f(a, b, ..., z)
而不是写 NOT <Boolean expression>
,其中 a
、b
、...、z
是给定布尔表达式 f(...)
中的变量。
如果不只是NOT
,还有布尔运算符MAYBE
和CANNOT
,那就容易多了。因此,您可以编写 WHERE MAYBE b = 2
或 WHERE CANNOT b = 2
,而不是在实际条件之前编写一堆 IS NULL 测试的复杂 OR 组合。
【讨论】:
【参考方案3】:!=
是一个二元运算符,如果它的两个参数不相等,则返回 true。
NOT
是一元运算符,它反转其参数,一个布尔表达式。
你怎么会认为它们是一样的?
例如,当a
是任何小于10 的值时,这个表达式:a < 10
为真。这个条件可以被否定:NOT a < 10
。否定这个条件使得它在相反的情况下成立,即当 a 不小于 10 时。它与 a >= 10
相同。
当a
是任何小于10 或任何大于10 的值时,表达式a != 10
为真。这与用NOT
否定的条件完全不同。
【讨论】:
【参考方案4】:NOT 运算符和 != 几乎都有类似的用途。两者都用于 sql 查询的 Where 子句中。
NOT 运算符在特定条件不成立时显示记录。 示例:
SELECT * FROM Employees
WHERE NOT Country='Germany'
将为您提供所有在德国以外国家/地区的员工的记录。
!=
运算符类似地检查两个操作数的值是否相等,如果值不相等则条件为真。
例子:
SELECT * FROM Employees
WHERE Country!='Germany'
将为您提供所有国家/地区列中包含德国以外国家/地区的行。
【讨论】:
以上是关于SQL 中的 NOT 和 != 运算符有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle:使用 SQL 或 PL/SQL 查找动态 SQL 中的错误位置
sql (SSMS) 中的 CONVERT 函数是不是可以替换为 Pyspark.sql 中的类似函数。换句话说,有没有类似的功能?