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

我们在设计数据库时,常常会允许一些字段为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)


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341