关于MySQL中的NULL值,我们先做个小实验。

创建一个简单的表:

CREATE TABLE `t_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `stu_no` varchar(10) DEFAULT NULL COMMENT '学生编号',
  `stu_name` varchar(50) DEFAULT NULL COMMENT '学生姓名',
  `class_id` int(11) DEFAULT NULL COMMENT '班级id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入几行测试数据:

INSERT INTO `t_student` VALUES ('1', '1001', 'John', '301');
INSERT INTO `t_student` VALUES ('2', null, 'Hank', '301');
INSERT INTO `t_student` VALUES ('3', null, 'Tony', '301');
INSERT INTO `t_student` VALUES ('4', '1008', 'Tom', '302');

mysql查询字段为null时替换 mysql查询值为空或者null_mysql

一、NULL值的含义

在上面插入的数据中,id等于2和3的记录,他们的学号还没有确定,现在是NULL值,如果我们想要把这样的数据查询出来做一下统计,于是就写了下面这样的SQL:

SELECT * FROM t_student
WHERE stu_no=NULL

很奇怪的是,上面的SQL没有返回任何记录,明明表里面有两行学号为NULL的数据啊,为什么没有查出来呢?

如果反向思维一下,既然等于NULL这个查询条件出不来数据,那么不等于NULL值的条件总该有结果了吧?id等于1和4的记录,他们的学号不为NULL值,正常应该返回这两条记录,写个SQL试试:

SELECT * FROM t_student
WHERE stu_no!=null

但依然没有返回任何结果,等于和不等于都查询不出来数据,这真是奇怪,看来这个NULL比较特殊。

我们看看MySQL官网对于NULL值的一个说明:

mysql查询字段为null时替换 mysql查询值为空或者null_MySQL_02

翻译过来大致意思就是:NULL值可能会令人感到惊讶,直到你习惯了它。从概念上来讲,NULL意味着“一个缺失的未知值”,它与其他值的处理方式有些不同。

换句话说,NULL值是未知的,它可能是这个值,也可能是另外一个值,也可能不是这个值,也可能不是另外一个值,总之,它很诡异,行踪不定,所以不管什么值与NULL进行比较,结果都是NULL。另外,NULL也不是空字符串,空字符串是一个确定的值,而NULL不是。

如果需要查找NULL的数据,我们需要使用IS NULL或者IS NOT NULL这样的条件,比如,我们要找到学号为NULL的数据,我们使用如下的SQL来查询:

SELECT * FROM t_student
WHERE stu_no IS NULL

这样就能把id等于2和3的记录查出来了:

mysql查询字段为null时替换 mysql查询值为空或者null_MySQL_03

还有个函数也是专门用来处理NULL值的:IFNULL(expr1,expr2),如果expr1的值为NULL,那么函数就返回expr2。

二、哪些情况下NULL值是相等的

先看看官网的说明:

mysql查询字段为null时替换 mysql查询值为空或者null_mysql_04

就是说,在使用DISTINCT,GROUP BY或者ORDER BY的时候,所有的NULL都是相等的。

比如我们想看看都有哪些学号(需要过滤掉重复的):

SELECT DISTINCT stu_no FROM t_student

它会返回三条记录,对于id等于2和3的记录,它们的stu_no字段为NULL,此时DISTINCT会认为它们是相等的,所以最终返回三条而不是四条记录:

mysql查询字段为null时替换 mysql查询值为空或者null_mysql查询字段为null时替换_05

三、聚合函数对于NULL的处理

像SUM(),MIN(),COUNT()这样的聚合函数,它们会忽略掉NULL值,也就是说,NULL值不会统计在内。

唯一例外的是COUNT(*),它统计数据表的行数,而不单个的字段值,如果是COUNT(字段名),则会把NULL值忽略掉,比如下面的SQL,分别返回4和2:

SELECT COUNT(*), COUNT(stu_no) FROM t_student

mysql查询字段为null时替换 mysql查询值为空或者null_数据_06

四、总结

1. NULL既不是0也不是空字符串,它是未知的,不能直接使用=、!=这样的方式来进行判断,需要IS (NOT) NULL或者IFNULL进行处理;

2. 对于分组、排序、去重等操作,它会认为NULL值是相等的;

3. 对于聚合函数,它会忽略掉NULL值,而COUNT(*)是个例外。

创作不易,烦请点赞、分享,感谢!

鸣谢:

https://dev.mysql.com/doc/refman/8.0/en/working-with-null.html