MySQL IS NULL
在 MySQL 中,NULL 是一个特殊的值,它代表什么都没有。它不是空,也不是 0。
IS NULL 运算符用来测试一个值是不是 NULL,如果是 NULL 返回 1,否则返回 0。
MySQL IS NULL 语法
IS NULL 是一个单目比较运算符,只需要一个操作数。IS NULL 运算符的语法是:
expression IS NULL
expression IS NOT NULL
expression 可以是一个字段名、一个值或者一个表达式。
IS NOT NULL 是 IS NULL 的否定运算。
IS NULL 和 IS NOT NULL 可以用在 SELECT 子句或者 WHERE 子句中。
MySQL IS NULL 运算规则
当 IS NULL 运算符左侧的操作数是 NULL 时,IS NULL 运算符返回 1,否则返回 0。
SELECT NULL IS NULL,0 IS NULL,1 IS NULL,(NULL IN (NULL)) IS NULL,(1+1) IS NULL;
+--------------+-----------+-----------+--------------------------+---------------+
| NULL IS NULL | 0 IS NULL | 1 IS NULL | (NULL IN (NULL)) IS NULL | (1+1) IS NULL |
+--------------+-----------+-----------+--------------------------+---------------+
| 1 | 0 | 0 | 1 | 0 |
+--------------+-----------+-----------+--------------------------+---------------+
IS NOT NULL 是 IS NULL 的否定运算。如果 IS NOT NULL 左侧的操作数不是 NULL 时,IS NOT NULL 运算符返回 1,否则返回 0。
SELECT NULL IS NOT NULL,0 IS NOT NULL,1 IS NOT NULL;
+------------------+---------------+---------------+
| NULL IS NOT NULL | 0 IS NOT NULL | 1 IS NOT NULL |
+------------------+---------------+---------------+
| 0 | 1 | 1 |
+------------------+---------------+---------------+
MySQL IS NULL 实例
在以下实例中,我们使用 Sakila 示例数据库中的 staff 表作为演示。
以下 SQL 语句使用 IS NULL 查询 staff 表中的那些没有设置密码的职员。
SELECT first_name, last_name, password FROM staff WHERE password IS NULL;
+------------+-----------+----------+
| first_name | last_name | password |
+------------+-----------+----------+
| Jon | Stephens | NULL |
+------------+-----------+----------+
样的,如果要查询 staff 表中的那些设置了密码的职员,请使用下面的 SQL 语句。
SELECT first_name, last_name, password FROM staff WHERE password IS NOT NULL;
+------------+-----------+------------------------------------------+
| first_name | last_name | password |
+------------+-----------+------------------------------------------+
| Mike | Hillyer | 8cb2237d0679ca88db6464eac60da96345513964 |
+------------+-----------+------------------------------------------+
总结
IS NULL 和 IS NOT NULL 是单目比较运算符。
使用 IS NULL 运算符检查一个值是否是 NULL。
IS NOT NULL 运算符是 IS NULL 的否定操作。
NULL IS NULL 的结果是 1。
MySQL EXISTS 的用法与实例
在 MySQL 中,EXISTS 操作符用来判断一个子查询是否返回数据行。如果一个子查询返回了至少一个数据行,则 EXISTS 的计算结果为 TRUE,否则计算结果为 FALSE。
EXISTS 语法
EXISTS 操作符是一个单目操作符,它需要一个子查询作为参数。EXISTS 操作符的语法如下:
SELECT column_name FROM table_name WHERE EXISTS(subquery);
EXISTS 一般用在 WHERE 子句中。
EXISTS 是一个单目操作符,它需要一个子查询 subquery 作为参数。
如果子查询 subquery 返回了至少一个数据行,则 EXISTS 的计算结果为 TRUE,否则计算结果为 FALSE。
EXISTS 运算时,一旦子查询找到一个匹配的行,EXISTS 运算就会返回。这对提高查询新能很有帮助。
EXISTS不关心子查询中的列的数量或者名称,它只在乎子查询是否返回数据行。所以在EXISTS的子查询中,无论你是使用SELECT 1还是SELECT *,亦或是 SELECT column_list,都不影响 EXISTS 运算的结果。
NOT EXISTS 则是 EXISTS 的否定操作。
EXISTS 实例
在以下实例中,我们使用 Sakila 示例数据库中的 film 表 和 language 表进行演示。
EXISTS 实例
下面的实例查询 language 表的一些语种,该语种在 film 表中存在相关语种的影片。
SELECT * FROM language WHERE EXISTS(SELECT * FROM film WHERE film.language_id = language.language_id);
+-------------+---------+---------------------+
| language_id | name | last_update |
+-------------+---------+---------------------+
| 1 | English | 2006-02-15 05:02:19 |
+-------------+---------+---------------------+
1 row in set (0.01 sec)
在上面的例子中,我们在 WHERE 子句中使用了 EXISTS 操作符。在 EXISTS 的子查询中,我们从 film 表中检索记录,检索的条件是 film.language_id = language.language_id。
在检索 language 表的每一行时,只要 film 表存在一行数据具有相同的 language_id, EXISTS 就返回 TRUE。然后进入 language 表的下一行,直到所有行都检索完成,然后返回 language 表中所有匹配成功的行。
最终的结果告诉我们,在 language 表中,只有语种 English 拥有影片。
NOT EXISTS 实例
上一个例子检索了 language 表中的拥有影片的行,下面的实例则检索了 language 表中的没有影片的行。这只是对上例中 EXISTS 的否定操作,只需要使用 NOT EXISTS 即可。如下:
SELECT * FROM language WHERE NOT EXISTS(SELECT * FROM film WHERE film.language_id = language.language_id);
+-------------+----------+---------------------+
| language_id | name | last_update |
+-------------+----------+---------------------+
| 2 | Italian | 2006-02-15 05:02:19 |
| 3 | Japanese | 2006-02-15 05:02:19 |
| 4 | Mandarin | 2006-02-15 05:02:19 |
| 5 | French | 2006-02-15 05:02:19 |
| 6 | German | 2006-02-15 05:02:19 |
+-------------+----------+---------------------+
5 rows in set (0.01 sec)
EXISTS 子查询的列
EXISTS 不关心子查询中的列的数量或者名称,它只在乎子查询是否返回数据行。我们看下面 3 个例子:
在子查询中使用 SELECT *
SELECT * FROM language WHERE EXISTS(SELECT * FROM film WHERE film.language_id = language.language_id);
在子查询中使用 SELECT 1
SELECT * FROM language WHERE EXISTS(SELECT 1 FROM film WHERE film.language_id = language.language_id);
在子查询中使用 SELECT column_name
SELECT * FROM language WHERE EXISTS( SELECT film_id FROM film WHERE film.language_id = language.language_id);
他们返回的结果都一样。这说明了 EXISTS 的子查询中的 SELECT 的列不影响 EXISTS 的结果。
EXISTS 与 IN
有时候 EXISTS 可以使用 IN 来实现。
SELECT *
FROM language
WHERE EXISTS(
SELECT *
FROM film
WHERE film.language_id = language.language_id
);
对应的 IN 操作符的版本是:
SELECT *
FROM language
WHERE language_id IN (
SELECT DISTINCT language_id
FROM film
);
大多数情况下,使用 EXISTS 的语句的性能比对应的使用 IN 的语句要好。
在子查询中使用 TABLE 语句
在 MySQL 8.0.19 和以后的版本中,我们可以直接在 EXISTS 或 NOT EXISTS 的子查询中使用 TABLE 语句。就像下面的一样:
SELECT column1 FROM t1 WHERE EXISTS (TABLE t2);
这相当于在子查询使用不带任何条件的 SELECT *。等同于如下的语句:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
总结
EXISTS 操作符用来判断一个子查询是否返回数据行。如果一个子查询返回了至少一个数据行,则 EXISTS 的计算结果为 TRUE,否则计算结果为 FALSE。
NOT EXISTS 则是 EXISTS 的否定操作。
EXISTS 运算的结果只与子查询是否返回数据行有关,子查询中的列的数量或者名称不影响运算结果。
大多数情况下,使用 EXISTS 的语句的性能比对应的使用 IN 的语句要好。