浅谈MySQL 中 null 值的那些坑

 更新时间:2025年09月11日 08:23:07   作者:Leaton Lee  
本文解析MySQL中null值的定义与常见问题,如比较运算符失效、WHERE条件误用、IN子查询异常,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

引言:null 值到底是什么?

在 MySQL 数据库中,null 是一个特殊的值,表示“未知”或“不存在”的含义。它不同于空字符串("")或零(0),而是明确表示该字段没有值。

然而,在实际开发中,很多人会遇到 null 值带来的“坑”。比如:

  • 查询时明明知道某个字段是 null,但 WHERE 条件却查不到结果。
  • 更新或插入数据时,不小心把 null 当成了普通值处理。

今天,我就结合自己的实战经验,详细讲解 null 值的常见问题及解决方法,帮助你避开这些“坑”!

第一部分:null 值的常见问题

问题 1:使用=和<>比较 null 的时候总是失败

很多人习惯用 = 或 <> 来判断字段是否为 null,但这是错误的!因为 null 是一个“未知值”,无法用普通的比较运算符进行判断。

示例场景:
假设有如下数据表:

CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    age INT,
    email VARCHAR(100)
);
 
INSERT INTO users VALUES 
(1, 'Alice', 25, 'alice@example.com'), 
(2, 'Bob', 30, NULL),
(3, 'Charlie', NULL, 'charlie@example.com'); 

执行以下查询:

SELECT * FROM users WHERE email = NULL; -- 查不到任何结果 
SELECT * FROM users WHERE email <> NULL; -- 同样查不到任何结果 

原因:
null 是一个不确定的值,无法用 = 或 <> 进行比较。任何与 null 的比较都会返回 false

问题 2:在WHERE子句中使用IS NULL和IS NOT NULL的时候忘记逻辑

有时候,开发者会忘记 IS NULL 和 IS NOT NULL 的正确用法,导致查询结果不符合预期。

示例场景:
继续使用上面的 users 表。

SELECT * FROM users WHERE email IS NULL; -- 正确的结果:Bob 的记录 
SELECT * FROM users WHERE age IS NOT NULL; -- 正确的结果:Alice 和 Charlie 的记录 

常见错误:

SELECT * FROM users WHERE email = NULL; -- 错误!返回空结果 

问题 3:在IN和NOT IN语句中使用 null 值

在 IN 和 NOT IN 语句中使用包含 null 的子查询时,可能会出现意想不到的结果。

示例场景:
假设有两张表:

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10, 2)
);
 
CREATE TABLE users (
    user_id INT PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(100)
);
 
INSERT INTO orders VALUES 
(1, 1, 100.00),
(2, 2, 200.00),
(3, 3, 300.00);
 
INSERT INTO users VALUES 
(1, 'Alice', 'alice@example.com'), 
(2, 'Bob', NULL),
(3, 'Charlie', 'charlie@example.com'); 

执行以下查询:

SELECT * FROM orders 
WHERE user_id IN (SELECT user_id FROM users WHERE email IS NULL); -- 正确的结果:Bob 的订单 

常见错误:

SELECT * FROM orders 
WHERE user_id IN (SELECT user_id FROM users WHERE email = NULL); -- 错误!返回空结果 

第二部分:解决 null 值问题的方法

方法 1:使用IS NULL和IS NOT NULL进行判断

这是处理 null 值的正确方式。

示例代码:

-- 查询 email 为 null 的用户 
SELECT * FROM users WHERE email IS NULL;
 
-- 查询 age 不为 null 的用户 
SELECT * FROM users WHERE age IS NOT NULL;

注意事项:

  • IS NULL 和 IS NOT NULL 只能用于判断字段是否为 null,不能与其他条件混合使用。
  • 如果需要结合其他条件查询,可以使用逻辑运算符 AND 或 OR

方法 2:在IN和NOT IN语句中正确处理 null 值

如果子查询中包含 null 值,可以使用 COALESCE 函数将其转换为其他值。

示例代码:

-- 正确的写法:使用 COALESCE 将 null 转换为一个不存在的值 
SELECT * FROM orders 
WHERE user_id IN (
    SELECT COALESCE(user_id, -1) FROM users WHERE email IS NULL 
);

解释:

  • COALESCE(user_id, -1) 表示如果 user_id 为 null,则返回 -1
  • 这样可以避免子查询中出现 null 值导致的逻辑错误。

方法 3:在插入和更新数据时明确处理 null 值

在插入或更新数据时,要确保字段允许存储 null 值。如果字段被定义为 NOT NULL,则必须提供非空值。

示例代码:

-- 插入 null 值 
INSERT INTO users (id, name, age, email) 
VALUES (4, 'David', NULL, 'david@example.com'); 
 
-- 更新 null 值 
UPDATE users SET email = NULL WHERE id = 4;

注意事项:

  • 如果字段被定义为 NOT NULL,插入或更新时必须提供有效值。
  • 可以使用 ALTER TABLE 修改字段的约束:
    ALTER TABLE users MODIFY COLUMN email VARCHAR(100) NULL;

第三部分:注意事项

注意 1:不要混淆 null 和空字符串

  • null 表示“不存在”或“未知”。
  • 空字符串("")表示字段确实存在,但内容为空。

示例场景:

-- 查询 email 为 null 的用户 
SELECT * FROM users WHERE email IS NULL;
 
-- 查询 email 为空字符串的用户 
SELECT * FROM users WHERE email = '';

注意 2:在排序时 null 的行为

在排序时,null 的行为可能与预期不同。默认情况下,null 会被视为最小值(在升序排列中排在最前面)。

示例代码:

-- 按 age 升序排列,null 排在最前面 
SELECT * FROM users ORDER BY age ASC;
 
-- 按 age 降序排列,null 排在最后面 
SELECT * FROM users ORDER BY age DESC;

注意 3:在聚合函数中处理 null 值

聚合函数(如 SUMAVGCOUNT)会忽略 null 值。

示例场景:

-- 计算所有用户的平均年龄(忽略 null 值)
SELECT AVG(age) FROM users;

总结:正确处理 null 值的三个关键点

  1. 使用 IS NULL 和 IS NOT NULL 进行判断
  2. 在子查询中使用 COALESCE 处理 null 值
  3. 在插入和更新时明确字段是否允许 null 值

通过以上方法,你可以轻松避开 null 值带来的“坑”,写出更健壮的 SQL 语句!

互动时间:你踩过哪些 null 值的坑?

  • 你是否曾经因为 null 值的问题而困惑?
  • 在实际开发中,你是如何处理 null 值的?

到此这篇关于MySQL 中 null 值的那些坑,你踩过吗?的文章就介绍到这了,更多相关MySQL null值坑内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • ‌MySQL中‌between and的基本用法‌操作方法

    ‌MySQL中‌between and的基本用法‌操作方法

    本文主要介绍了MySQL中BETWEEN AND操作符的基本用法,包括数值查询和时间范围查询,同时还详细解释了NOT BETWEEN AND的使用方法,并通过实例进行了详细的演示,其中,BETWEEN AND可以用于数值、日期等类型的字段,包括边界值
    2024-10-10
  • MySQL InnoDB MRR优化指南

    MySQL InnoDB MRR优化指南

    这篇文章主要给大家介绍了关于MySQL InnoDB MRR优化的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • mysql数据库设置utf-8编码的方法步骤

    mysql数据库设置utf-8编码的方法步骤

    这篇文章主要介绍了mysql数据库设置utf-8编码的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • 浅谈innodb_autoinc_lock_mode的表现形式和选值参考方法

    浅谈innodb_autoinc_lock_mode的表现形式和选值参考方法

    下面小编就为大家带来一篇浅谈innodb_autoinc_lock_mode的表现形式和选值参考方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • MySQL查看日志简单易懂保姆级教程

    MySQL查看日志简单易懂保姆级教程

    这篇文章主要给大家介绍了关于MySQL查看日志简单易懂保姆级教程的相关资料,在操作MySQL数据库的时候会留下每一个步骤的痕迹,那怎么查看呢?就可以用日志去查看,需要的朋友可以参考下
    2023-08-08
  • MySQL数据库事务transaction示例讲解教程

    MySQL数据库事务transaction示例讲解教程

    这篇文章主要为大家介绍了MySQL数据库事务transaction的示例讲解教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-10-10
  • windows下mysql 8.0.27 安装配置方法图文教程

    windows下mysql 8.0.27 安装配置方法图文教程

    这篇文章主要为大家详细介绍了windows下mysql 8.0.27 安装配置方法图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • 如何修改mysql数据库的max_allowed_packet参数

    如何修改mysql数据库的max_allowed_packet参数

    本篇文章是对修改mysql数据库的max_allowed_packet参数进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • Mysql迁移Postgresql的实现示例

    Mysql迁移Postgresql的实现示例

    本文主要介绍了Mysql迁移Postgresql的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • MySQL中的常用函数及用法总结

    MySQL中的常用函数及用法总结

    MySQL是一种常用的关系型数据库管理系统,它提供了许多内置函数来处理数据,本文将介绍MySQL中的各种常用函数,包括字符串函数、日期函数、数学函数、聚合函数等,需要的朋友可以参考下
    2023-06-06

最新评论