【mysql】SQL 中 IS 与 = 的区别:一个 NULL 值引发的思考

SQL 中 IS 与 = 的区别:一个 NULL 值引发的思考

为什么查询结果总是少一条数据?可能是 NULL 在捣鬼

在 SQL 查询中,很多开发者都曾遇到过这样的困惑:明明看起来正确的查询语句,返回的结果却总是与预期不符。这往往是因为没有正确理解 IS= 操作符的区别,特别是当遇到 NULL 值时。

一、核心区别:一句话总结

= 用于比较IS 用于比较NULL(或布尔常量)。

二、IS 与 = 的适用场景

三、详细对比表格

特性 = 操作符 IS 操作符
主要用途 普通值比较 NULL 值比较
与 NULL 比较 总是返回 UNKNOWN 正确返回 TRUE/FALSE
与非 NULL 值比较 正常工作 可能语法错误或逻辑错误
布尔值比较 支持(= TRUE/FALSE) 部分数据库支持(IS TRUE/FALSE)
可读性 常规比较,直观 专门用于 NULL,意图明确
三值逻辑处理 需要特别注意 NULL 专门为 NULL 设计

四、NULL 比较的陷阱与实际示例

错误示例

sql 复制代码
-- 这行代码永远返回空结果集!
SELECT * FROM users WHERE deleted_at = NULL;

正确示例

sql 复制代码
-- 正确查找未删除的用户
SELECT * FROM users WHERE deleted_at IS NULL;

五、为什么 NULL 如此特殊?

NULL 在 SQL 中表示"未知"或"不存在"的值,它不等于任何值,甚至不等于它自己。这就是为什么不能使用 = 比较 NULL 的原因。

SQL 使用三值逻辑:

  • TRUE(真)
  • FALSE(假)
  • UNKNOWN(未知)

任何与 NULL 的比较都会返回 UNKNOWN,而 WHERE 子句只返回条件为 TRUE 的行。

六、NOT IN 子查询中的 NULL 陷阱

问题代码

sql 复制代码
SELECT *
FROM customers
WHERE customers.id NOT IN (
    SELECT customerid FROM orders
);

问题分析

如果 orders 表中的 customerid 包含 NULL 值,上述查询将返回空结果集,因为:
x NOT IN (1, 2, NULL) 等价于 x <> 1 AND x <> 2 AND x <> NULL

x <> NULL 的结果是 UNKNOWN,导致整个表达式为 UNKNOWN,最终被视为 FALSE。

解决方案

使用 NOT EXISTS 替代 NOT IN:

sql 复制代码
SELECT *
FROM customers c
WHERE NOT EXISTS (
    SELECT 1
    FROM orders o
    WHERE o.customerid = c.id
);

七、不同数据库的差异说明

数据库 IS 布尔值支持 = 布尔值支持 建议
MySQL 支持 (IS TRUE/IS FALSE) 支持 (= TRUE/= FALSE) 统一使用 =
PostgreSQL 支持 支持 统一使用 =
SQL Server 不支持 支持 使用 =
SQLite 有限支持 支持 使用 =

八、实际工作中的应用建议

  1. NULL 检查一律使用 IS NULL 或 IS NOT NULL
  2. 布尔值比较统一使用 = 操作符(保持代码一致性)
  3. 避免在 NOT IN 子查询中包含 NULL 值
  4. 优先使用 NOT EXISTS 而不是 NOT IN(避免 NULL 问题)
  5. 在复杂查询中显式处理 NULL(使用 COALESCE 或 ISNULL 函数)

九、记忆口诀

NULL 用 IS,非 NULL 用 =

布尔两者都可以,统一风格最重要

NOT IN 里有陷阱,NOT EXISTS 更可靠

总结

理解 IS= 的区别是编写正确 SQL 查询的基础。关键是要记住 NULL 的特殊性------它表示未知值,不能使用常规的比较操作符。掌握了这个概念,你就能避免许多常见的 SQL 陷阱,写出更加健壮和可靠的查询语句。

下次当你发现查询结果与预期不符时,不妨先检查一下:是不是 NULL 值在捣鬼?是不是应该用 IS 而不是 =?

相关推荐
Lkstar9 分钟前
万字长文Query改写与多路召回实战|从HyDE到RRF融合,召回率提升22%的完整方案
数据库·人工智能·llm
IT新视界22 分钟前
星环科技ArgoDB:基于一体化架构构建数据全生命周期安全底座
数据库·科技·安全·架构
峥无27 分钟前
MySQL DML 操作(CRUD)总结
数据库·mysql
数据库小学妹1 小时前
SQL Server数据库同步工具怎么选?6款方案对比+信创迁移避坑清单
数据库·经验分享·sqlserver·dba
不剪发的Tony老师1 小时前
国产数据库之GaussDB:固若金汤
数据库·gaussdb
雨辰AI2 小时前
生产级实测:SpringBoot3 + 达梦数据库接口从 200ms 优化至 20ms 完整调优指南
java·数据库·spring boot·后端·政务
凡人叶枫2 小时前
Effective C++ 条款39:明智而审慎地使用 private 继承
java·数据库·c++·嵌入式开发
基德爆肝c语言2 小时前
MySQL表的操作
前端·数据库·mysql
GreatSQL3 小时前
gt-checksum v4.0.0 新功能解读系列文章(1):断点续传——大任务中断不再从头跑
mysql
TDengine (老段)3 小时前
TDengine 连接算子 — Inner/Outer/ASOF/Window Join 的实现与使用
大数据·数据库·物联网·哈希算法·时序数据库·tdengine·涛思数据