做订单报表时,状态字段存的是 0 和 1,运营要求列表直接显示「未付款」「已付款」。不用改表结构,一条 sql if 判断就能在查询里把值翻译过去。

MySQL 的 IF 函数吃三个参数

IF(条件, 真值, 假值) 的写法跟 Excel 的 IF 一样。比如 SELECT IF(pay_status = 1, '已付款', '未付款') AS status_text FROM orders;,条件成立返回第二个参数,否则返回第三个。嵌套两三层还能忍,再多就该换 CASE 了。

空值处理用 IFNULL 更顺手

手机号字段为 NULL 时页面显示空白,IFNULL(phone, '未填写') 直接补默认值。Oracle 里对应 NVL,SQL Server 用 ISNULL,功能差不多,换数据库时留意函数名对不上。

IFNULL 只认 NULL,空字符串它管不了,这种脏数据得先用 TRIM 处理,或者在写入时就拦住。

CASE WHEN 适合多分支

按金额分档、按省份归大区这类场景,IF 套 IF 很难读。改写成这样:

SELECT CASE WHEN amount >= 1000 THEN '大额' WHEN amount >= 100 THEN '中额' ELSE '小额' END AS level FROM orders;

CASE 还能写进 ORDER BY 做自定义排序,比如让待处理状态排最前面,这点 IF 做不到。

日常统计还有个常见写法:SUM(IF(status = 1, 1, 0)) 直接算出已付款单数,比套一层子查询轻。GROUP BY 之后按天、按渠道各算一列,报表 SQL 能短不少。

两个容易踩的坑

IF 函数只有 MySQL 认,SQL Server 用的是 IIF,标准 SQL 只支持 CASE。项目以后可能换库,直接上 CASE 最稳。另外 WHERE 里别写 IF(status = 1, 1, 0) = 1,这样索引会失效,直接写 status = 1 就行。

判断很简单:二选一用 IF,多分支或者要兼容其他库用 CASE WHEN,空值用 IFNULL。大表上每行都算一遍函数,代价不小,能挪到业务层的判断就别全压在 SQL 里。sql if 只是查询层的小工具,把条件放在 SQL 里还是代码里,看哪边维护的人多。