--- tags: Database --- # SQL 中的 `NULL` * `NULL` 代表了遺失、未知或是不適用。 > Generally, you use the NULL value to indicate that the **data is missing, unknown, or not applicable**. > > [name=[MySQL NULL / MySQL TUTORIAL](http://www.mysqltutorial.org/mysql-null/)] 而數值零或空字串值,這兩者都表示已知的值,並不等於是 `NULL`。 > 幾個情境示範: > > ``` > | Name | Phone | > |---------|--------------| > | Celine | '0987654321' | 有電話 > | Antonio | '' | 他真的沒電話 > | Gary | NULL | 不知道他有沒有電話 > | Doggy | NULL | 狗不會有電話 > ``` > [color=lightblue] * `NULL` 不會等於任何其他東西,因為 `NULL` 是未知的,它可以是任何值。 > **A `NULL` value is not equal to anything, even itself.** If you compare a `NULL` value with another `NULL` value or any other value, the result is `NULL` because the value of each `NULL` value is unknown. > > [name=[MySQL NULL / MySQL TUTORIAL](http://www.mysqltutorial.org/mysql-null/)] `NULL` 不會等於另一個 `NULL`,所以搜尋 `value = NULL` 是不會有結果的。 ```sql SELECT * FROM `user` WHERE `phone` = NULL; ✖︎ ⬇ SELECT * FROM `user` WHERE `phone` IS NULL; ✔︎ ``` 另外 `NULL` 也可以被用在 Unique key,MySQL 會將其視為不同的值。 > 假設現在有一組 Unique key `btree__name__address` ,接下來新增兩筆資料。 > > ```sql > INSERT INTO `user` (`name`, `address`) VALUES > ('Antonio', NULL), > ('Antonio', NULL); > ``` > > 以上狀況是可以成功新增的,因為 Antonio ~~搞不好家財萬貫~~,就是有這麼多棟房子,只是我們不知道在哪而已。 > [color=lightblue] * SQL 使用了[三值邏輯 three-valued logic](https://zh.wikipedia.org/wiki/%E4%B8%89%E5%80%BC%E9%80%BB%E8%BE%91),以 `NULL` 代表 unkown。 ![](https://i.imgur.com/igaAjvJ.png =100x) 哇母災 ![](https://i.imgur.com/8X5WUm5.png) ![](https://i.imgur.com/xz4Kasp.png) > 可以用有沒有吃飽來當情境想像,列幾項例子,以此類推: > * `True AND True` :我吃飽你也吃飽,我們都吃飽 → `True` > * `True AND Unkown` :我吃飽你不知道有沒有吃飽,我們不一定都吃飽 → `Unkown` > * `True AND False` :我吃飽你沒吃飽,我們沒有都吃飽 → `False` > * `True OR Unkown`:我吃飽你不知道有沒有吃飽,我們其中一個人有吃飽 → `True` > > [color=lightblue] > 幾個 `IN` 的比較: > ```sql > SELECT 1 IN (1, NULL); -- return True > SELECT 1 NOT IN (1, NULL); -- return False > > SELECT 2 IN (1, NULL); -- return NULL > SELECT 2 NOT IN (1, NULL); -- return NULL > > SELECT NULL IN (1, NULL); -- return NULL > SELECT NULL NOT IN (1, NULL); -- return NULL > -- NULL 可以是任何值,不一定會與後方的 NULL 相同,所以是 NULL > ``` > [color=lightblue] * 與數學運算符結果的結果永遠是 unknown。 ![](https://i.imgur.com/qRE2gJs.png =130x) 不知道就是不知道,算再久還是不知道。 ## Function ### [`ISNULL`](http://www.mysqltutorial.org/mysql-isnull-function/) 如果參數是 `NULL` 就回傳 `1`,否則回傳 `0`。 ```sql SELECT ISNULL(NULL); -- 1 SELECT ISNULL(1); -- 0 SELECT ISNULL(1 + NULL); -- 1 SELECT ISNULL(1 / 0); -- 1 ``` > If a `DATE` or `DATETIME` column that has a `NOT NULL` constraint and contains a special date `'0000-00-00'`, you can use the `IS NULL` operator to find such rows. > > [name=[MySQL IS NULL / MySQL TUTORIAL](http://www.mysqltutorial.org/mysql-is-null/)] ### [`IFNULL`](http://www.mysqltutorial.org/mysql-ifnull/) 接受兩個 arguments,如果第一個參數不是 `NULL` 就回傳,如果是 `NULL` 則回傳第二個參數。 ```sql SELECT IFNULL(1, 'N/A'); -- returns 1 SELECT IFNULL('', 'N/A'); -- returns '' SELECT IFNULL(NULL, 'N/A'); -- returns 'N/A' ``` ### [`NULLIF`](http://www.mysqltutorial.org/mysql-nullif/) 接受兩個 arguments,如果相同就回傳 `NULL`,否則回傳第一個參數。 > 情境可以搭配 `COALESCE` 使用,我們希望出來的優先聯絡資訊是有值的,而空字串也代表有值,並非我們預期的結果,因此可以加上 `NULLIF` 修改。: > > ```sql > INSERT INTO `user` (`name`, `phone`, `email`) VALUES > ('Celine', '', 'celine@mail'); > > SELECT `name`, COALESCE( > `phone`, `email` > ) `contact` FROM `user`; > > | name | contact | > |--------|---------| > | Celine | '' | > > ⬇ > > SELECT `name`, COALESCE( > NULLIF(`phone`, ''), > NULLIF(`email`, '') > ) `contact` FROM `user`; > > | name | contact | > |--------|-------------| > | Celine | celine@mail | > ``` > > > > [color=lightblue] ### [`COALESCE`](http://www.mysqltutorial.org/mysql-coalesce/) 接受一連串的 arguments,回傳第一個非 `NULL` 的值。 ## [Comparison with null](https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_equal-to) > NULL-safe equal. This operator performs an equality comparison like the = operator, but returns 1 rather than NULL if both operands are NULL, and 0 rather than NULL if one operand is NULL. ``` 1 <=> 1 # 1 null <=> null # 1 null <=> 1 # 0 1 <=> 2. # 0 ``` ## 參考資料 * [The Three-Valued Logic of SQL / Modern SQL](https://modern-sql.com/concept/three-valued-logic) * [MySQL NULL / MySQL TUTORIAL](http://www.mysqltutorial.org/mysql-null/)