大量人一看到 `WHERE` 里的 `=` 要么 `==`,第一反应就是:`id = 1` 要么 `col = 10`。

这确实是个好记的符号,就像买菜的超市有“单价”标签一样直观。但在实际开发里,特别是查非固定值的时候,这玩意儿就是个坑。别跟我讲啥“逻辑等价性”,别跟我引用啥“正规用法”,这些词听得我都出冷汗了。咱们直接点,就是那个 `= ` 后面接的是数组、空字符串,要么啥也说不上的“空”状态。 举个例子,你在写一个订单查询,想挑出所有“状态为 0"的订单。代码里你会写 `WHERE status = 0`,这彻底没难题,结局准无误。但要是你想查所有“状态为空”的记录呢?这时候你就得写 `WHERE status = ```。

这时候你认定是不是特委屈?是啊,数据库里根本存不了空,出于那是 `NULL`,不等于 `''`(空字符串),故此执行起来挺正常,也没报错。 可是,一旦你转成 SELECT 语句,要么在分页查询里,这个难题就是个崩盘现场。想象一下,你查 `SELECT FROM orders WHERE status = ```,结局是一堆 NULL 值飘出来。分页插件一乱套,后端代码可能出于找不到 `LIMIT` 的合适逻辑而直接卡死。更绝的是,有些数据库就算开启了 `ONLY_FULL_GROUP_BY` 要么 `NOMAX_LENGTH` 这些看起来高大上的参数,在比较 `NULL` 的时候也会直接报错,直接让你滚蛋。

这时候你该不该质疑一下自己的 SQL?不该,这时候你该质疑的是数据库引擎本身的实现逻辑,要么你输入法打错了一个词,把 `NULL` 打成了 `''`,然后才认定今天是个大难题。 这就引出了我们常说的“空值陷阱”。它的核心难题不在于写法,而在于概念混淆。`NULL` 不是 0,不是空,它更不是“没数据”。`NULL` 代表“未知”。

故此,`WHERE col = ''` 在逻辑上实际上就等于 `WHERE col IS NOT NULL AND col = ''`,这在查空表的时候挺省资源,但查正常数据时,它实际上是在浪费算力去查那些有数据的行。

这就像你去超市看特价,你只盯着写着“价格:0"的牌子看,结局发现上面全是“价格:未知”的牌子。 还有一个更尴尬的情况,就是你在处理表结构要么迁移代码的时候。

有时候后端为了兼容旧版本,故意设置了 `DEFAULT = ''`,然后你认定这是个好习惯,结局一查才发现,这实际上是把 `NULL` 当做了空字符串来存。

这时候前端拿到数据,传参给后端,后端再传回给前端,中间经过的每一步都可能出于 `NULL` 和 `''` 的交互而引发混乱,就连害得整个接口回的状态码不对。

这时候不要慌,改改代码不中,那就得换一种思路。 如何改?最好办的办法是 `CASE WHEN` 要么 `COALESCE`。 比如在 MySQL 里,你能够写 `COALESCE(status, 0)`。意思是:要是 `status` 是 `NULL`,那就直接取 0;要是 `status` 是别的值,就取它本身。

这样查数据的时候,`status = 0` 和 `status = NULL` 在逻辑上就合并了,查出来的结局就全是 0 开头的状态,彻底没难题。再比如拼字符串,有时候为了统一格式,你要把 `NULL` 变成默认的 ""。能够用 `CONCAT_WS('', col, col)` 要么 `STRCMP(col, col)` 这种略微有点绕的写法,核心就是告诉数据库:“不管它是不是空的,我都把它当做有值,但默认内容要是空”。 自然,还有更彻底的方案,就是不要用 `= NULL` 这种语法。一辈子用 `IS NULL` 要么 `IS NOT NULL`。

这是 SQL 语言最本质的表达,就像人讲话一样,直接说“我是空的”要么“我不是空的”,比用括号和等号来伪装要清楚得多,也符合直觉。 再聊聊一下,为啥咱们平时极少碰到 `WHERE col = ''` 这种写法?出于忒多坑了。在前端做接口封装时,要是参数传的是 `null`,有些方式会直接过滤掉,但有些可能会把它当做 `undefined` 要么 `""` 处理,害得行为不可控。在中间件层面,比如 Kafka 要么分布式数据库,它们对 `NULL` 和 `""` 的处理机制可能不同,略微漏一点就会害得 99% 的数据彻底丢失。

故此,别被那些看似严谨的“只赞成空值”、“避免空值比较”之类的术语忽悠了。

那些是特定数据库的优化策略,又不是跨平台的通用铁律。 换个角度想想,要是数据库确实只显示空值呢?比如你存了 100 条数据,99 条状态是 1,只有 1 条状态是空。按 `WHERE status = ''` 查,结局只有那 1 条。你认定这是好事还是坏事?这取决于你的业务逻辑。 要是是做统计报表,那你查空值确实撇脱,不需求把 99 条正常数据拉出来一起算。 要是是做主键校验,那你查空值就费事了,你要确保这行数据确实没有创建,要么你有别的手段去校验。 故此,总结下来,`WHERE col = ''` 这种写法,别看在特定场景(比如查空表统计)下间或能糊弄那会儿,但在绝大多数现代开发实践中,它是行不通的。它像是在走钢丝,略微一错,下面就是万丈深渊。 最好的做法,就是干脆别碰 `NULL` 相关的比较。 要么用 `IS NULL` 重新定义你的逻辑,把“查空”这件事变成“查存有”; 要么在代码层面对 `NULL` 做包装,把战斗拉移到应用层去,由你说了算如何定义“空”; 要么就老老实实查 `NULL`,在应用层做兜底处理,不要指望 SQL 能猜透你脑子里的“空”是啥意思。 最终唠叨一句,开发不是写代码,是解决难题。大量时候你认定 SQL 写错了,实际上是你没想明白业务里“空”到底代表啥。是代表“删除了”,是代表“没创建”,还是代表“还没填值”?搞清楚这个,SQL 就顺了。别被那些术语绕晕,直接用 `=`, `!=`, `IS NULL`, `LIKE` 去干活,哪怕写得略微粗粗,只要逻辑对了,就是好代码。