在MySQL中,
NULL
值表示一个未知值,它不同于
或空字符串
''
,并且不等于它自身。
我们如果将
NULL
值与另一个
NULL
值或任何其他值进行比较,则结果为
NULL
,因为一个不知道是什么的值(
NULL
值)与另一个不知道是什么的值(
NULL
值)比较,其值当然也是一个不知道是什么的值(
NULL
值)。
然而我们通常,使用
NULL
值来表示数据丢失,未知或不适用的情况。 例如,潜在客户的电话号码可能为
NULL
,并且可以稍后添加。所以我们创建表时,可以通过使用
NOT NULL
约束来指定列是否接受
NULL
值。接下来,我们来创建一张
leads
表,并且以此为依据来具体了解下:
CREATE TABLE leads (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
source VARCHAR(255) NOT NULL,
email VARCHAR(100),
phone VARCHAR(25)
);
我们可以看出来,
id
是主键列,它不接受任何
NULL
值,然后
first_name
,
last_name
和
source
列使用
NOT NULL
约束,因此,不能在这些列中插入任何
NULL
值,而
email
和
phone
列则可接受
NULL
值。
所以,我们可以在insert语句中使用
NULL
值来指定数据丢失。 例如,以下语句将一行插入到线索表中。 因为电话号码丢失,所以使用
NULL
值:
INSERT INTO leads(first_name,last_name,source,email,phone)
VALUE('John','Doe','Web Search','[email protected]',NULL);
因为
email
列的默认值为
NULL
,可以按照以下方式在
INSERT
语句中省略电子邮件:
INSERT INTO leads(first_name,last_name,source,phone)
VALUES('Lily','Bush','Cold Calling','(408)-555-1234'),
('David','William','Web Search','(408)-888-6789');
完事如果我们要将列的值设置为
NULL
,可以使用赋值运算符(
=
)。 例如,要将
David William
的手机(
phone
)更新为
NULL
,请使用以下
UPDATE
语句:
UPDATE leads
SET
phone = NULL
WHERE
id = 3;
但是如果使用order by子句按升序对结果集进行排序,则MySQL认为
NULL
值低于其他值,因此,它会首先显示
NULL
值。以下查询语句按照电话号码(
phone
)升序排列:
SELECT
*
FROM
leads
ORDER BY phone;
执行上面查询语句,结果如下:
+----+------------+-----------+--------------+---------------------+----------------+
| id | first_name | last_name | source | email | phone |
+----+------------+-----------+--------------+---------------------+----------------+
| 1 | John | Doe | Web Search | [email protected] | NULL |
| 3 | David | William | Web Search | NULL | NULL |
| 2 | Lily | Bush | Cold Calling | NULL | (408)-555-1234 |
+----+------------+-----------+--------------+---------------------+----------------+
如果使用
ORDER BY DESC
,
NULL
值将显示在结果集的最后:
SELECT
*
FROM
leads
ORDER BY phone DESC;
执行上面查询语句,结果如下:
+----+------------+-----------+--------------+---------------------+----------------+
| id | first_name | last_name | source | email | phone |
+----+------------+-----------+--------------+---------------------+----------------+
| 2 | Lily | Bush | Cold Calling | NULL | (408)-555-1234 |
| 1 | John | Doe | Web Search | [email protected] | NULL |
| 3 | David | William | Web Search | NULL | NULL |
+----+------------+-----------+--------------+---------------------+----------------+
3 rows in set
我们如果要在查询中测试
NULL
,可以在where子句中使用
IS NULL
或
IS NOT NULL
运算符。例如,要获得尚未提供电话号码的潜在客户,请使用
IS NULL
运算符,如下所示:
SELECT
*
FROM
leads
WHERE
phone IS NULL;
执行上面查询语句,结果如下:
+----+------------+-----------+------------+---------------------+-------+
| id | first_name | last_name | source | email | phone |
+----+------------+-----------+------------+---------------------+-------+
| 1 | John | Doe | Web Search | [email protected] | NULL |
| 3 | David | William | Web Search | NULL | NULL |
+----+------------+-----------+------------+---------------------+-------+
2 rows in set
我们还可以使用
IS NOT
运算符来获取所有提供电子邮件地址的潜在客户:
SELECT
*
FROM
leads
WHERE
email IS NOT NULL;
执行上面查询语句,结果如下:
+----+------------+-----------+------------+---------------------+-------+
| id | first_name | last_name | source | email | phone |
+----+------------+-----------+------------+---------------------+-------+
| 1 | John | Doe | Web Search | [email protected] | NULL |
+----+------------+-----------+------------+---------------------+-------+
1 row in set
然而,即使
NULL
不等于
NULL
,
GROUP BY
子句中视两个
NULL
值相等,来看下sql实例:
SELECT
email, count(*)
FROM
leads
GROUP BY email;
该查询只返回两行,因为其邮箱(
email
)列为
NULL
的行被分组为一行,结果如下所示:
+---------------------+----------+
| email | count(*) |
+---------------------+----------+
| NULL | 2 |
| [email protected] | 1 |
+---------------------+----------+
2 rows in set
我们要知道在列上使用唯一约束或
UNIQUE
索引时,可以在该列中插入多个
NULL
值,在这种情况下,MySQL认为
NULL
值是不同的。接下来我们通过为
phone
列创建一个
UNIQUE
索引来验证这一点:
CREATE UNIQUE INDEX idx_phone ON leads(phone);
这里我们要注意,如果使用BDB存储引擎的话,mysql会认为
NULL
值相等,因此我们不能将多个
NULL
值插入到具有唯一约束的列中。
既然知道了null的好处和坏处,我们就来看下在mysql中应该如何处理它吧。mysql一共提供了三个函数,分别是IFNULL,COALESCE和NULLIF。
我们来分别看下,首先,
IFNULL
函数接受两个参数。 如果
IFNULL
函数不为
NULL
,则返回第一个参数,否则返回第二个参数。例如,如果不是
NULL
,则以下语句返回电话号码(
phone
),否则返回
N/A
,而不是
NULL
。来看个实例:
SELECT
id, first_name, last_name, IFNULL(phone, 'N/A') phone
FROM
leads;
执行上面查询语句,得到以下结果:
+----+------------+-----------+----------------+
| id | first_name | last_name | phone |
+----+------------+-----------+----------------+
| 1 | John | Doe | N/A |
| 2 | Lily | Bush | (408)-555-1234 |
| 3 | David | William | N/A |
+----+------------+-----------+----------------+
3 rows in set
完事就是
COALESCE
函数,它接受参数列表,并返回第一个非
NULL
参数。 例如,可以使用
COALESCE
函数根据信息的优先级按照以下顺序显示线索的联系信息:
phone
,
email
和
N/A
。以下是案例:
SELECT
id,
first_name,
last_name,
COALESCE(phone, email, 'N/A') contact
FROM
leads;
执行上面查询语句,得到以下代码:
+----+------------+-----------+---------------------+
| id | first_name | last_name | contact |
+----+------------+-----------+---------------------+
| 1 | John | Doe | [email protected] |
| 2 | Lily | Bush | (408)-555-1234 |
| 3 | David | William | N/A |
+----+------------+-----------+---------------------+
3 rows in set
最后就是
NULLIF
函数了,它接受两个参数。如果两个参数相等,则
NULLIF
函数返回
NULL
。 否则,它返回第一个参数。在列中同时具有
NULL
和空字符串值时,
NULLIF
函数很有用。 例如,我们错误地将以下行插入到
leads
表中:
INSERT INTO leads(first_name,last_name,source,email,phone)
VALUE('Thierry','Henry','Web Search','[email protected]','');
因为
phone
是一个空字符串:
''
,而不是
NULL
。所以,如果我们想获得潜在客户的联系信息,则最终得到空
phone
,而不是电子邮件,如下所示:
SELECT
id,
first_name,
last_name,
COALESCE(phone, email, 'N/A') contact
FROM
leads;
执行上面查询语句,得到以下代码:
+----+------------+-----------+---------------------+
| id | first_name | last_name | contact |
+----+------------+-----------+---------------------+
| 1 | John | Doe | [email protected] |
| 2 | Lily | Bush | (408)-555-1234 |
| 3 | David | William | N/A |
| 4 | Thierry | Henry | |
+----+------------+-----------+---------------------+
我们如果要解决这个问题,就要使用
NULLIF
函数将电话与空字符串(
''
)进行比较,如果相等,则返回
NULL
,否则返回电话号码:
SELECT
id,
first_name,
last_name,
COALESCE(NULLIF(phone, ''), email, 'N/A') contact
FROM
leads;
执行上面查询语句,得到以下代码:
+----+------------+-----------+--------------------------+
| id | first_name | last_name | contact |
+----+------------+-----------+--------------------------+
| 1 | John | Doe | [email protected] |
| 2 | Lily | Bush | (408)-555-1234 |
| 3 | David | William | N/A |
| 4 | Thierry | Henry | [email protected] |
+----+------------+-----------+--------------------------+
4 rows in set
好啦,本次记录就到这里了。如果感觉不错的话,请多多点赞支持哦。。。