美文网首页
谈谈关系数据库中null的处理

谈谈关系数据库中null的处理

作者: chimpansee | 来源:发表于2019-08-02 17:49 被阅读0次

我们在设计数据库时,常常会允许一些字段为null。但是在后续处理null时,由于null的特殊性,可能在算术运算、逻辑运算中带来一些始料不及的情况,我们来总结写null的处理特例情况。

  • 算术运算,比较运算

null在算术运算代表不知道的值,所以任何算术表达式中出现了null,其结果也是一个不知道的值,也就是null

mysql> select * from person;
+------+------+-------+------+
| id   | name | memo  | age  |
+------+------+-------+------+
|    1 | mike | memo1 |   30 |
|    2 | john | memo2 | NULL |
|    3 | tom  | memo3 |   25 |
|    4 | mary | NULL  | NULL |
|    5 | mary | NULL  | NULL |
+------+------+-------+------+
5 rows in set (0.00 sec)

mysql> select age*2 from person;
+-------+
| age*2 |
+-------+
|    60 |
|  NULL |
|    50 |
|  NULL |
|  NULL |
+-------+
5 rows in set (0.00 sec)

mysql>
mysql> select age+2 from person;
+-------+
| age+2 |
+-------+
|    32 |
|  NULL |
|    27 |
|  NULL |
|  NULL |
+-------+
5 rows in set (0.00 sec)

mysql>
mysql> select null>1 ;
+--------+
| null>1 |
+--------+
|   NULL |
+--------+
1 row in set (0.00 sec)

mysql> select null<1;
+--------+
| null<1 |
+--------+
|   NULL |
+--------+
1 row in set (0.00 sec)

mysql> select null=1;
+--------+
| null=1 |
+--------+
|   NULL |
+--------+
1 row in set (0.00 sec)



  • 逻辑运算

  • 与运算:
    true and null= null;
    false and null=false;
    null and null=null;

mysql> select true and null ;
+---------------+
| true and null |
+---------------+
|          NULL |
+---------------+
1 row in set (0.00 sec)

mysql> select false and null;
+----------------+
| false and null |
+----------------+
|              0 |
+----------------+
1 row in set (0.00 sec)

mysql> select null and null;
+---------------+
| null and null |
+---------------+
|          NULL |
+---------------+
1 row in set (0.00 sec)

mysql>

  • 或运算
    true or null=true;
    flase or null=null;
    null or null=null;
mysql> select true or null;
+--------------+
| true or null |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

mysql> select false or null
    -> ;
+---------------+
| false or null |
+---------------+
|          NULL |
+---------------+
1 row in set (0.00 sec)

mysql> select null or null;
+--------------+
| null or null |
+--------------+
|         NULL |
+--------------+
1 row in set (0.00 sec)

mysql>
  • 非运算
    not(null)=null;
mysql> select not(null);
+-----------+
| not(null) |
+-----------+
|      NULL |
+-----------+
1 row in set (0.00 sec)

mysql>
  • where 语句

如果想通过select将期待的结果集查询出来,其where条件必须是true。其他值包括(null,false)一概不予返回。

mysql> select * from person ;
+------+------+-------+------+
| id   | name | memo  | age  |
+------+------+-------+------+
|    1 | mike | memo1 |   30 |
|    2 | john | memo2 | NULL |
|    3 | tom  | memo3 |   25 |
|    4 | mary | NULL  | NULL |
|    5 | mary | NULL  | NULL |
+------+------+-------+------+
5 rows in set (0.00 sec)

mysql> select * from person where age>25;
+------+------+-------+------+
| id   | name | memo  | age  |
+------+------+-------+------+
|    1 | mike | memo1 |   30 |
+------+------+-------+------+
1 row in set (0.00 sec)

mysql>
mysql> select * from person where age is null;
+------+------+-------+------+
| id   | name | memo  | age  |
+------+------+-------+------+
|    2 | john | memo2 | NULL |
|    4 | mary | NULL  | NULL |
|    5 | mary | NULL  | NULL |
+------+------+-------+------+
3 rows in set (0.00 sec)

  • join语句

在join条件中,如果有null值存在,结果是不匹配。

mysql> select * from person ;
+------+------+-------+------+
| id   | name | memo  | age  |
+------+------+-------+------+
|    1 | mike | memo1 |   30 |
|    2 | john | memo2 | NULL |
|    3 | tom  | memo3 |   25 |
|    4 | mary | NULL  | NULL |
|    5 | mary | NULL  | NULL |
+------+------+-------+------+
5 rows in set (0.00 sec)

mysql> select * from teacher;
+------+------+------+
| id   | name | age  |
+------+------+------+
|    1 | mike |   30 |
|    4 | mary |   35 |
+------+------+------+
2 rows in set (0.00 sec)
mysql> select * from person natural join teacher;
+------+------+------+-------+
| id   | name | age  | memo  |
+------+------+------+-------+
|    1 | mike |   30 | memo1 |
+------+------+------+-------+
1 row in set (0.00 sec)

mysql>
  • 集合语句

集合语句中,多个null会被当作重复值来处理,有点类似空格似的。

mysql> select * from person;
+------+------+-------+------+
| id   | name | memo  | age  |
+------+------+-------+------+
|    1 | mike | memo1 |   30 |
|    2 | john | memo2 | NULL |
|    3 | tom  | memo3 |   25 |
|    4 | mary | NULL  | NULL |
|    5 | mary | NULL  | NULL |
+------+------+-------+------+
5 rows in set (0.00 sec)

mysql> select * from teacher;
+------+------+------+
| id   | name | age  |
+------+------+------+
|    1 | mike |   30 |
|    4 | mary |   35 |
|    2 | john | NULL |
+------+------+------+
3 rows in set (0.00 sec)

mysql> select name ,age from person union select name,age from teacher;
+------+------+
| name | age  |
+------+------+
| mike |   30 |
| john | NULL |
| tom  |   25 |
| mary | NULL |
| mary |   35 |
+------+------+
5 rows in set (0.00 sec)

mysql> select age from person union select age from teacher;
+------+
| age  |
+------+
|   30 |
| NULL |
|   25 |
|   35 |
+------+
4 rows in set (0.00 sec)

mysql>
  • group by 语句

在group by语句中,多个null会被当作重复值。

mysql> select * from person;
+------+------+-------+------+
| id   | name | memo  | age  |
+------+------+-------+------+
|    1 | mike | memo1 |   30 |
|    2 | john | memo2 | NULL |
|    3 | tom  | memo3 |   25 |
|    4 | mary | NULL  | NULL |
|    5 | mary | NULL  | NULL |
+------+------+-------+------+
5 rows in set (0.00 sec)
mysql> select count(*) from person group by age;
+----------+
| count(*) |
+----------+
|        1 |
|        3 |
|        1 |
+----------+
3 rows in set (0.00 sec)

mysql> select count(*) from person group by name,age;
+----------+
| count(*) |
+----------+
|        1 |
|        1 |
|        1 |
|        2 |
+----------+
4 rows in set (0.00 sec)
  • select 语句

select对于字段的处理默认不会去重,对null也不例外。

mysql> select age from person;
+------+
| age  |
+------+
|   30 |
| NULL |
|   25 |
| NULL |
| NULL |
+------+
5 rows in set (0.00 sec)

mysql> select distinct age from person;
+------+
| age  |
+------+
|   30 |
| NULL |
|   25 |
+------+
3 rows in set (0.00 sec)

mysql>
  • 聚集函数

聚集函数在处理数据前,会剔除掉null,这与算术处理中逻辑不同,这是因为考虑到聚集函数结果不会仅仅因为一个null而成为null,从而失去实际的计算意义。但是如果处理结果是null,结果也就显示null。

mysql> select * from person;
+------+------+-------+------+
| id   | name | memo  | age  |
+------+------+-------+------+
|    1 | mike | memo1 |   30 |
|    2 | john | memo2 | NULL |
|    3 | tom  | memo3 |   25 |
|    4 | mary | NULL  | NULL |
|    5 | mary | NULL  | NULL |
+------+------+-------+------+
5 rows in set (0.00 sec)

mysql> select count(age) from person;
+------------+
| count(age) |
+------------+
|          2 |
+------------+
1 row in set (0.00 sec)
mysql>
mysql> select count(age) from person where age is null;
+------------+
| count(age) |
+------------+
|          0 |
+------------+
1 row in set (0.00 sec)

mysql> select max(age) from person where age is null;
+----------+
| max(age) |
+----------+
|     NULL |
+----------+
1 row in set (0.00 sec)

mysql> select avg(age) from person where age is null;
+----------+
| avg(age) |
+----------+
|     NULL |
+----------+
1 row in set (0.00 sec)


相关文章

网友评论

      本文标题:谈谈关系数据库中null的处理

      本文链接:https://www.haomeiwen.com/subject/kdwldctx.html