Theoretical difference
<=>
Operator
<=>
is a safe null-comparison operator. That means you may use it and do not worry if you'll compare with NULL
- it will behave properly. To illustrate, here is a simple query:
mysql> SELECT v, v<=>NULL, v<=>1, v<=>0 FROM test;
+------+----------+-------+-------+
| v | v<=>NULL | v<=>1 | v<=>0 |
+------+----------+-------+-------+
| 1 | 0 | 1 | 0 |
| NULL | 1 | 0 | 0 |
+------+----------+-------+-------+
2 rows in set (0.00 sec)
So what <=>
does - is normal comparison, with paying attention is one or two compared operands are NULL
.
IS NULL
On the other hand, IS NULL
is very similar. It will check if checked argument is NULL
or not. But - no, it's not exactly same as using <=>
- at least, because IS NULL
will return boolean value:
mysql> SELECT v, v IS NULL FROM test;
+------+-----------+
| v | v IS NULL |
+------+-----------+
| 1 | 0 |
| NULL | 1 |
+------+-----------+
2 rows in set (0.00 sec)
How they are equivalent
But - yes, we can replace <=>
with IS NULL
, using IF
. That will be done with:
mysql> SELECT v, IF(v IS NULL, 1, 0) AS `v<=>NULL`, IF(v IS NULL, 0, v=1) AS `v<=>1`, IF(v IS NULL, 0, v=0) AS `v<=>0` FROM test;
+------+----------+-------+-------+
| v | v<=>NULL | v<=>1 | v<=>0 |
+------+----------+-------+-------+
| 1 | 0 | 1 | 0 |
| NULL | 1 | 0 | 0 |
+------+----------+-------+-------+
2 rows in set (0.00 sec)
Thus, <=>
is equivalent for combination of IF
, IS NULL
and plain comparison.
Practical difference
I already said, that <=>
can be replaced with IS NULL
and IF
- but <=>
, actually, have one great benefit. It may be used safely in prepared statements. Imagine that we want to check some condition with incoming value. Using <=>
we can do this, using prepared statement:
mysql> PREPARE stmt FROM 'SELECT * FROM test WHERE v<=>?';
Query OK, 0 rows affected (0.00 sec)
Statement prepared
And now we can just do not care if we'll pass NULL
or not - it will work properly:
mysql> SET @x:=1;
Query OK, 0 rows affected (0.03 sec)
mysql> EXECUTE stmt USING @x;
+------+
| v |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
Or with NULL
:
mysql> SET @x:=NULL;
Query OK, 0 rows affected (0.00 sec)
mysql> EXECUTE stmt USING @x;
+------+
| v |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
That, of course, will be same for all drivers, which are relying on prepared statements (such as PDO for PHP, for example).
Well. we can replace that with IS NULL
- but <=>
is a great thing to use in this case, so we can have our prepared statement short and clean.