SQL中四则运算需注意NULL静默失效、整数除法截断、除零安全处理、类型差异及括号优先级,应显式转换类型、用CASE或NULLIF防错、命名别名并严格加括号。

SELECT 中直接写 +、-、*、/ 就行,但要注意 NULL 和数据类型
SQL 的 SELECT 语句天然支持四则运算,不需要额外函数包装。比如 price * 1.1 算含税价、end_time - start_time 算时长(部分数据库支持),都是合法写法。但实际用起来,两个坑最常绊人:
-
NULL参与任何算术运算结果全是NULL—— 不是报错,而是静默失效,容易漏查 - 整数列做除法时,有些数据库(如 PostgreSQL、SQL Server)默认截断小数,
5 / 2得2而不是2.5
遇到除零错误 division by zero 怎么安全处理
直接写 revenue / cost 很危险:只要 cost 为 0 或 NULL,整行结果就变 NULL(或直接报错,取决于数据库)。别依赖应用层兜底,SQL 层就得防住:
- 用
CASE WHEN显式判断:CASE WHEN cost = 0 THEN NULL ELSE revenue / cost END - MySQL 可用
NULLIF(cost, 0)把 0 转成NULL,再配合COALESCE(revenue / NULLIF(cost, 0), 0)统一兜底 - PostgreSQL 支持
NULLIF()同样有效;SQL Server 推荐用NULLIF(cost, 0)配合ISNULL()
不同数据库对除法结果类型的处理差异
同样写 SELECT 7 / 3,结果可能完全不同:
- PostgreSQL:返回
2(整数除法),要小数得写7.0 / 3或CAST(7 AS numeric) / 3 - MySQL:默认返回
2.3333(自动转浮点),但若字段是INT且参与计算,仍可能截断 - SQL Server:整数相除得整数,
7/3 = 2;必须至少一个操作数转成FLOAT或DECIMAL
跨库迁移或写通用脚本时,别假设除法一定带小数——显式类型转换最稳。
用别名让算术字段可读、可引用
算术表达式本身没名字,不加 AS 别名的话,结果列名可能是 price*1.1 这种难看的字符串,而且后续 ORDER BY 或 HAVING 里没法直接用。务必命名:
- 简单命名:
SELECT price * 1.1 AS price_with_tax FROM products - 别名能被
ORDER BY直接引用:ORDER BY price_with_tax DESC - 但注意:在
WHERE里不能用这个别名,因为WHERE执行早于SELECT计算——得重复写表达式或改用子查询
真正容易被忽略的是运算优先级和括号:写 base + discount * rate 和 (base + discount) * rate 差异巨大,别省那对括号。

















