null参与算术运算结果必为null,这是sql三值逻辑的强制标准,表示“未知值”而非零或空字符串;coalesce是跨数据库兼容的null处理首选函数。

NULL参与算术运算必然得NULL,这是三值逻辑的底层约定
不是bug,是SQL标准强制行为。NULL在SQL里不代表“零”或“空字符串”,而是“未知值”。当你写 price + discount,而其中一个是 NULL,数据库无法判断这个未知值该加多少——它既可能极大,也可能为负,甚至根本不存在。所以结果只能是 NULL,表示“运算结果未知”。这跟数学里的未定义不同,是明确的、可预测的语义传递。
常见错误:误用= NULL或直接参与计算
很多人写 WHERE amount = NULL 或 SELECT price * 0.9 FROM orders 后发现结果不对,其实问题不在语法错,而在没意识到 price 是 NULL 时整行表达式就“失效”了:
-
100 * NULL→NULL(不是报错,也不是跳过) -
SUM(price)自动忽略NULL行,但price + tax只要任一为NULL,整列就是NULL -
COALESCE(price, 0) + COALESCE(tax, 0)才能得到确定数值
不同数据库对NULL运算的兼容性差异很小,但函数行为有区别
所有主流SQL引擎(MySQL、PostgreSQL、SQL Server、Oracle)都遵守“NULL污染”原则,但处理默认值的函数名不同:
- 通用且标准:
COALESCE(col, 0)—— 推荐优先用,跨库兼容 - MySQL专属:
IFNULL(col, 0) - SQL Server专属:
ISNULL(col, 0) - Oracle专属:
NVL(col, 0)
注意:ISNULL() 和 IFNULL() 都只接受两个参数,而 COALESCE() 支持任意多个,且按顺序返回第一个非 NULL 值。
容易被忽略的聚合场景:SUM()忽略NULL,但表达式里嵌套NULL仍会中断
SUM() 确实跳过 NULL,但如果你写的是 SUM(price * rate),而某行 rate 是 NULL,那 price * rate 先变成 NULL,再被 SUM() 忽略——看起来像“少了数据”,其实是中间步骤已丢失信息。真正安全的做法是:
- 先清理输入:
SUM(COALESCE(price, 0) * COALESCE(rate, 1)) - 或过滤前提:
SUM(price * rate) WHERE price IS NOT NULL AND rate IS NOT NULL
别指望数据库替你猜意图;NULL一旦混入表达式链,就会像墨水滴进清水里一样扩散,直到你显式截断它。











