mysql中NULL大坑
mysql中NULL大坑
參考網址:
建表規範
https://mp.weixin.qq.com/s?__biz=MzU4ODI1MjA3NQ==&mid=2247490967&idx=2&sn=fc92dc46ad2b6b2c2964c06f6277c4f7&chksm=fddecb53caa94245107a004935add8c0ccb059830f61d31ef404d172c3b07f87c0f576aa9a62&mpshare=1&scene=23&srcid=0923GipnyxKQhFHoObIlFU9W&sharer_sharetime=1600911081363&sharer_shareid=9d1e76e919cc0b2f3ca23ed1f5ef67a8#rd
說明:
mysql建表規約是不允許列的值為NULL的
NULL存在的坑
我們先看⼀下效果,然後在解釋,⽰例如下:
mysql> create table test5 (a int not null,b int,c varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test5 values (1,2,‘a’),(3,null,‘b’),(4,5,null);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
±–±-----±-----+
| a | b | c |
±–±-----±-----+
| 1 | 2 | a |
| 3 | NULL | b |
| 4 | 5 | NULL |
±–±-----±-----+
3 rows in set (0.00 sec)
上⾯我們建立了⼀個表test5,3個欄位,a不能為空,b、c可以為空,插⼊了3條資料,睜
⼤眼睛看效果了:
mysql> select * from test5 where b>0;
±–±-----±-----+
| a | b | c |
±–±-----±-----+
| 4 | 5 | NULL |
±–±-----±-----+
2 rows in set (0.00 sec)
mysql> select * from test5 where b<=0;
Empty set (0.00 sec)
mysql> select * from test5 where b=NULL;
Empty set (0.00 sec)
mysql> select * from test5 t where t.b between 0 and 100;
±–±-----±-----+
| a | b | c |
±–±-----±-----+
| 1 | 2 | a |
| 4 | 5 | NULL |
±–±-----±-----+
2 rows in set (0.00 sec)
mysql> select * from test5 where c like ‘%’;
±–±-----±-----+
| a | b | c |
±–±-----±-----+
| 1 | 2 | a |
| 3 | NULL | b |
±–±-----±-----+
2 rows in set (0.00 sec)
mysql> select * from test5 where c in (‘a’,‘b’,NULL);
±–±-----±-----+
| a | b | c |
±–±-----±-----+
| 1 | 2 | a |
| 3 | NULL | b |
±–±-----±-----+
2 rows in set (0.00 sec)
mysql> select * from test5 where c not in (‘a’,‘b’,NULL);
Empty set (0.00 sec)
認真看⼀下上⾯的查詢:
上⾯帶有條件的查詢,對欄位b進⾏條件查詢的,b的值為NULL的都沒有出現。
對c欄位進⾏like '%'查詢、in、not查詢,c中為NULL的記錄始終沒有查詢出來。
between and查詢,為空的記錄也沒有查詢出來。
結論:查詢運算子、like、between and、in、not in對NULL值查詢不起效。
那NULL如何查詢呢?繼續向下看
IS NULL/IS NOT NULL(NULL值專⽤查詢)
上⾯介紹的各種運算子對NULL值均不起效,mysql為我們提供了查詢空值的語法:IS
NULL、IS NOT NULL。
IS NULL(返回值為空的記錄)
select 列名 from 表名 where 列 is null;
查詢指定的列的值為NULL的記錄。
如:
mysql> create table test7 (a int,b varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test7 (a,b) values (1,‘a’),(null,‘b’),(3,null),
(null,null),(4,‘c’);
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from test7;
±-----±-----+
| a | b |
±-----±-----+
| 1 | a |
| NULL | b |
| 3 | NULL |
| NULL | NULL |
| 4 | c |
±-----±-----+
5 rows in set (0.00 sec)
mysql> select * from test7 t where t.a is null;
±-----±-----+
| a | b |
±-----±-----+
| NULL | b |
| NULL | NULL |
±-----±-----+
2 rows in set (0.00 sec)
mysql> select * from test7 t where t.a is null or t.b is null;
±-----±-----+
| a | b |
±-----±-----+
| NULL | b |
| 3 | NULL |
| NULL | NULL |
±-----±-----+
3 rows in set (0.00 sec)
IS NULL(返回值不為空的記錄)
select 列名 from 表名 where 列 is not null;
查詢指定的列的值不為NULL的記錄。
如:
mysql> select * from test7 t where t.a is not null;
±-----±-----+
| a | b |
±-----±-----+
| 1 | a |
| 3 | NULL |
| 4 | c |
±-----±-----+
3 rows in set (0.00 sec)
mysql> select * from test7 t where t.a is not null and t.b is not
null;
±-----±-----+
| a | b |
±-----±-----+
| 1 | a |
| 4 | c |
±-----±-----+
2 rows in set (0.00 sec)
<=>(安全等於)
<=>:既可以判斷NULL值,又可以判斷普通的數值,可讀性較低,⽤得較少
⽰例:
mysql> create table test8 (a int,b varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test8 (a,b) values (1,‘a’),(null,‘b’),(3,null),
(null,null),(4,‘c’);
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from test8;
±-----±-----+
| a | b |
±-----±-----+
| 1 | a |
| NULL | b |
| 3 | NULL |
| NULL | NULL |
| 4 | c |
±-----±-----+
5 rows in set (0.00 sec)
mysql> select * from test8 t where t.a<=>null;
±-----±-----+
| a | b |
±-----±-----+
| NULL | b |
| NULL | NULL |
±-----±-----+
2 rows in set (0.00 sec)
mysql> select * from test8 t where t.a<=>1;
±-----±-----+
| a | b |
±-----±-----+
| 1 | a |
±-----±-----+
1 row in set (0.00 sec)
可以看到<=>可以將NULL查詢出來。
經典⾯試題
下⾯的2個sql查詢結果⼀樣麼?
select * from students;
select * from students where name like ‘%’;
結果分2種情況:
當name沒有NULL值時,返回的結果⼀樣。
當name有NULL值時,第2個sql查詢不出name為NULL的記錄。
總結
• like中的%可以匹配⼀個到多個任意的字元,_可以匹配任意⼀個字元
• 空值查詢需要使⽤IS NULL或者IS NOT NULL,其他查詢運算子對NULL值⽆效
• 建議建立表的時候,儘量設定表的欄位不能為空,給欄位設定⼀個預設值
•<=>(安全等於)玩玩可以,建議少使⽤
• sql⽅⾯有問題的歡迎留⾔?或者加我微信itsoku交流。