最可能漏了ELSE;WHEN条件未覆盖全(如NULL、空字符串、边界值)且无ELSE时,数据库默认返回NULL而非报错,易被误判为数据缺失而非逻辑漏洞。

SELECT中CASE WHEN返回一堆NULL,最可能漏了ELSE
只要WHEN条件没覆盖全(比如字段有NULL、空字符串、边界值),又没写ELSE,数据库就按标准返回NULL——不是报错,所以容易被当成“数据缺失”而不是“逻辑漏洞”。
- 显式写
ELSE '未知'或ELSE 0,比依赖默认NULL更可控 - 如果业务上真需要
NULL,也请写成ELSE NULL,让意图可读 - 用
COALESCE()兜底是补救手段,但治标不治本;源头加ELSE才是正解
WHEN分支返回值类型不一致会直接报错
PostgreSQL会严格拒绝CASE WHEN flag THEN 'true' ELSE 0 END这种混用字符串和数字的写法;MySQL可能静默转成0,但结果不可靠。
- 所有
THEN和ELSE分支必须返回同一大类类型:全是字符串、全是数字、全是日期 - 数值类优先统一为
DECIMAL或INTEGER,避免浮点精度问题 - 字符串类别名字段若后续要排序或比较,注意长度是否足够(比如
ELSE '超长描述'可能被截断)
条件顺序错了,后面分支永远不触发
比如写成WHEN age > 18 THEN '成人' WHEN age > 60 THEN '老年',那65岁的人只会进第一个分支。
- 范围判断务必从大到小或从小到大排好序,别交叉
- 用
BETWEEN时确认边界包含关系,age BETWEEN 20 AND 30包含20和30 - 涉及
IS NULL或IS NOT NULL的判断,放在显式值判断之前还是之后,取决于业务优先级
嵌套三层以上CASE WHEN,调试成本飙升
不是语法不支持,而是人眼很难快速定位哪条路径生效,尤其加上缩进错位、括号漏配,查半天才发现是第2层ELSE写在了第1层结尾。
- 把主干逻辑先抽成独立计算列,比如先算
category,再基于它分二级标签 - 避免
WHEN ... THEN CASE ... END这种内联嵌套,拆成子查询或CTE更清晰 - 上线前一定用边界数据跑:空值、负数、超长字符串、刚好卡在临界点的值
NULL的ELSE——它不会报错,但可能让报表少统计几百条订单,而你得翻半天日志才意识到问题出在SQL里。

















