力扣:584.寻找用户推荐人

89 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

描述

给定表 customer ,里面保存了所有客户信息和他们的推荐人。

+------+------+-----------+
| id   | name | referee_id|
+------+------+-----------+
|    1 | Will |      NULL |
|    2 | Jane |      NULL |
|    3 | Alex |         2 |
|    4 | Bill |      NULL |
|    5 | Zack |         1 |
|    6 | Mark |         2 |
+------+------+-----------+

写一个查询语句,返回一个客户列表,列表中客户的推荐人的编号都 不是 2。

对于上面的示例数据,结果为:

+------+
| name |
+------+
| Will |
| Jane |
| Bill |
| Zack |
+------+

解析

这是一道数据库题目,本来不想记录这道题的,因为大家可能都会觉得太简单了,我第一眼也是这么认为,没想到有个小细节被忽略了,我第一眼看过去直接就想着答案就是:

SELECT name FROM customer WHERE referee_Id <> 2;

仔细想一下或者尝试一下结果,其实这是一个错的答案,这个查询结果只会返回一个Zach,这里大家就会想起来,这六条数据中有三条是NULL值,而对于NULL值的比较,就涉及到一个知识点。

在MySQL中的比较结果有三种,分别是TRUE、FALSE和UNKNOWN,在查询语句中,使用where或者having时,只有结果是true的时候才会被输出,false和unknown都不会被输出。

那什么时候会出现unknown的结果呢,当空值NULL与另一个值,这个值可以是NULL进行比较时,他们的运算结果为unknown,也就是我们上面的这个referee_Id <> 2条件,当referee_Id为NULL时,比较结果是unknown,是不会被返回的。

此外,空值NULL进行算术运算的结果也是NULL,如:NULL+1的结果是NULL。

因此,正确的写法有以下两种:

-- 方式一
SELECT name FROM customer WHERE referee_id != 2 OR referee_id IS NULL;
​
-- 方式二
SELECT name FROM customer WHERE referee_id != 2 
union all
SELECT name FROM customer WHERE referee_id IS NULL;
​

这里更推荐 方式二,因为使用or会导致索引失效的情况,但是使用union的时候要注意一点,如果是union all的话是不会去重的,比如结果集中有两个name是Will的,那都会被查出来,单独使用union的话,会进行去重,也就是结果集只会有一条Will的返回值。

运行结果:

执行结果:通过

执行用时:491 ms, 在所有 MySQL 提交中击败了71.39%的用户

内存消耗:0 B, 在所有 MySQL 提交中击败了100.00%的用户