MySQL 中的 <=> 运算符是什么?

194

我正在处理一位前任的代码,其中一个查询语句写着:

WHERE p.name <=> NULL

在这个查询中,<=>代表什么意思?它是否等同于=?还是语法错误?

但是它没有显示任何错误或异常。我已经知道在MySQL中,<>等同于!=


27
太空船操作符 - Moha the almighty camel
4
@Mhd.Tahawi,我们需要一个可以直接搜索运算符的谷歌。 - Pacerier
1
@Pacerier - 我在大约5年前发现了这个网站http://symbolhound.com(不知道是否有更好的替代品) - Andrew
10个回答

279

简短总结

<=>NULL 安全 equal 运算符。

和普通的 = 运算符一样,比较两个值并返回结果,结果要么是 0(不相等),要么是 1(相等);换句话说:'a' <=> 'b' 的结果是 0'a' <=> 'a' 的结果是 1

不同于普通的 = 运算符,NULL 的值没有特殊含义,因此它永远不会返回 NULL 作为可能的结果;所以:'a' <=> NULL 的结果是 0NULL <=> NULL 的结果是 1

用途

当两个操作数都可能包含 NULL 并且您需要在两个列之间得到一致的比较结果时,这个运算符非常有用。

另一个用例是在使用预处理语句时,例如:

... WHERE col_a <=> ? ...

在这里,占位符可以是标量值或NULL,而不必更改查询的任何内容。

相关运算符

除了<=>,还有另外两个可用于与NULL比较的运算符,即IS NULLIS NOT NULL;它们是ANSI标准的一部分,因此支持其他数据库,而不像<=>那样,它是MySQL特定的。

你可以把它们看作是MySQL <=> 的专业化版本:

'a' IS NULL     ==> 'a' <=> NULL
'a' IS NOT NULL ==> NOT('a' <=> NULL)

基于此,您的特定查询(片段)可以转换为更便携的形式:

WHERE p.name IS NULL

支持

SQL:2003标准引入了一个谓词,其工作方式与MySQL的<=>运算符完全相同,形式如下:

IS [NOT] DISTINCT FROM 

以下内容被普遍支持,但相对较为复杂:

CASE WHEN (a = b) or (a IS NULL AND b IS NULL)
     THEN 1
     ELSE 0
END = 1

16
完全不一样;<=>需要两个操作数,而IS(NOT)NULL只需要一个操作数;这有很大的区别……在这方面它与=本身一样有用。 - Ja͢ck
12
IS NULLIS NOT NULL是SQL标准中的语法。<=>是MySQL特有的扩展。 - Daniel Dinnyes
5
想知道 MySQL 是否可以在 is not distinct from 运算符上使用索引。 - Denis de Bernardy
4
@Pacerier 不,a <=> b 的反向是 NOT(a <=> b) - Ja͢ck
4
@zzlalani,太空船运算符实际上非常有用。它和“正常”的编程语言和数学中的=一样有用。a = b要么是true,要么是false,除了在SQL领域,他们设法洗脑了那里的人口,认为它也可以是null,而对于其他人来说,这根本没有任何意义。事实上,整个Java、C#、Javascript、PHP等领域如果null == null给你的结果不是true,他们会反叛的。即使是像Javascript这样错误的语言,也知道undefined == undefined=true - Pacerier
显示剩余5条评论

65

<=> NULL-safe equal to operator

该运算符执行类似于 = 运算符的相等比较,但是如果两个操作数都为 NULL,则返回 1 而不是 NULL,如果一个操作数为 NULL,则返回 0 而不是 NULL。

请参阅文档

示例:

您应该使用 IS NOT NULL。(比较运算符 = 和 <> 对表达式两侧均有 NULL 的情况都会返回 UNKNOWN。)

SELECT * 
FROM table 
WHERE YourColumn IS NOT NULL;

也可以否定null安全的等号运算符,但这不是标准的SQL。

SELECT *
FROM table 
WHERE NOT (YourColumn <=> NULL);

2
更正:<=> 应称为等于运算符,而 = 则是不安全的NULL等于运算符。 - Pacerier

31

它是NULL安全相等操作符

<=>操作符用于比较带有NULL值的字段。如果使用普通=(等于)操作符进行比较,其中一个值为NULL,那么将返回NULL。而使用<=>操作符将返回true或false。<=>操作符与IS NULL相同。

根据手册:

<=>执行类似于=操作符的相等比较,但如果两个操作数都是NULL,则返回1,如果一个操作数是NULL,则返回0,而不是NULL。

mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
        -> 1, NULL, NULL

编辑:虽然晚了,但需要补充一个重要的侧面说明:NOT <=> 也不是一回事

顺便提一下:

NOT <=>

还有一个点 NOT <=>,用于将 NULL 值与字段进行比较。如果使用普通的!=或<>(不相等)运算符进行比较,当比较值中有一个为 NULL 时,会返回 NULL。将 NOT 应用于 <=> 运算符返回 true 或 false。将 NOT 应用于 <=> 运算符与 IS NOT NULL 相同。

例如:

SELECT NULL != NULL,         //--Result is NULL
   NOT NULL <=> NULL,        //--Result is 0
   NULL IS NOT NULL;         //--Result is 0

1
NOT <=> 不是一个运算符,它是应用于 op1 <=> op2 的结果的 NOT - Ja͢ck
@Jack:是的,你说得对。已经更新了答案!加上这个是为了强调一下 :) - Rahul Tripathi
1
所以我猜没有 <!=> 运算符。 - Kip
@kip:没有! - Rahul Tripathi

21

<=> 是MySQL的空安全“等于”运算符。根据手册

空安全等于。该运算符执行类似于=运算符的相等比较,但是如果两个操作数都为NULL,则返回1而不是NULL,如果一个操作数为NULL,则返回0而不是NULL。

mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
        -> 1, NULL, NULL

非常感谢您提供准确、富有资源和声誉的回答!:) - undefined

15

<=>空值安全的等于运算符。它等同于标准 SQL 中的 is not distinct from 运算符。其行为最好通过真值表来解释:

a b a <=> b
1 0 false
1 1 true
1 null false*
null null true*

* 注意,这个运算符不会像其他运算符一样返回未知(由 null 表示)。


12

NULL安全相等运算符。该运算符执行类似于=运算符的相等比较,但是如果两个操作数都为NULL,则返回1而不是NULL;如果有一个操作数为NULL,则返回0而不是NULL。

mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
        -> 1, NULL, NULL

它的意义:

如果你将一个NULL值与非NULL值进行比较,将得到NULL。如果你想检查一个值是否为NULL。

等号操作符(<=>) 将NULL视为正常值,因此如果两个值都为NULL,则返回1(不是NULL),如果其中一个值为NULL,则返回0(不是NULL):

例如:

 SELECT NULL <=> NULL -- 1
 SELECT TRUE <=> TRUE -- 1
 SELECT col1 <=> col2 FROM myTable

10

根据MySQL文档

NULL安全等于。该操作符执行类似于“=”的等于比较,但是当两个运算数都为NULL时,返回1,而不是NULL;当一个运算数为NULL时,返回0而不是NULL。

使用<=>操作符的示例:

SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;

这将返回:

1, 1, 0

正常情况下使用=运算符的一个例子是:


SELECT 1 = 1, NULL = NULL, 1 = NULL;

它将返回:

1, NULL, NULL

<=> 运算符与 = 运算符非常相似,不同之处在于 <=> 永远不会返回 NULL


5

这是一个NULL安全的等于运算符。请查看描述


1
mysql> SELECT * FROM t JOIN t2 WHERE t2.ids = t.ids;
+----+------+----+------+
| id | ids  | id | ids  |
+----+------+----+------+
|  1 |    1 |  1 |    1 |
|  2 |    2 |  2 |    2 |
|  5 |    6 |  5 |    6 |
|  6 |    7 |  6 |    7 |
+----+------+----+------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM t JOIN t2 WHERE t2.ids <=> t.ids;
+----+------+----+------+
| id | ids  | id | ids  |
+----+------+----+------+
|  1 |    1 |  1 |    1 |
|  2 |    2 |  2 |    2 |
|  3 | NULL |  3 | NULL |
|  4 | NULL |  3 | NULL |
|  3 | NULL |  4 | NULL |
|  4 | NULL |  4 | NULL |
|  5 |    6 |  5 |    6 |
|  6 |    7 |  6 |    7 |

-1

operand1=operand2operand1<=>operand2之间的区别在于前者会在任何一个操作数为null时返回null,而后者则会根据操作数的值返回10,即使其中有一个为null。

相比之下:

  • select null = null,返回null;但是select null <=> null,返回1
  • select null = 'abc',返回null;但是select null <=> 'abc',返回0

错误。如果col1为空,它并不总是返回true!请尝试使用SELECT null <=> 'a' - the_nuts
我已经纠正了,感谢您指出问题。 - light

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