优先用coalesce,因其是sql标准函数、支持多参数、跨数据库兼容;ifnull仅mysql特有、限两参数、类型处理宽松易致隐式转换错误且不兼容其他数据库。

视图里用IFNULL还是COALESCE?先看数据库类型
MySQL 里 IFNULL() 最顺手,但 PostgreSQL、Oracle、SQL Server 都不认它;跨库或未来可能迁移时,COALESCE() 是唯一安全选择。两者行为一致:遇到 NULL 就返回备选值,但 IFNULL() 只接受两个参数,COALESCE() 支持多个,比如 COALESCE(col1, col2, 'N/A') 能 fallback 到第二字段再 fallback 到字符串。
常见错误是以为 IFNULL(nickname, '匿名用户') 能处理空字符串——它不能。'' 不是 NULL,所以原样返回。真要覆盖 NULL 和空串,得套一层 NULLIF(TRIM(nickname), ''):
COALESCE(NULLIF(TRIM(nickname), ''), '匿名用户')
脱敏视图中NULL字段导致CASE WHEN漏判怎么办
写 CASE WHEN phone IS NOT NULL THEN ... ELSE ... END 很常见,但漏掉了空字符串、全空格、或格式非法(如身份证号带字母)的情况。结果就是:NULL 打码了,'' 或 ' ' 却原样暴露。
- 必须显式检查空字符串:
phone != ''(MySQL)或NULLIF(TRIM(phone), '') IS NOT NULL(通用) - 长度校验前先
TRIM(),否则LENGTH('138****1234 ')算出来是 15+,正则也匹配不上 - 正则判断优先于长度判断,因为
REGEXP在 MySQL 8.0+ 中能同时校验格式和非空,比LENGTH() = 11更可靠
错误示例:CASE WHEN LENGTH(phone) = 11 THEN ... —— 若 phone 是 '1381234'(8位),长度不等,直接走 ELSE 分支,但没防住 NULL 或空串。
AVG/SUM等聚合后除法报错,视图里怎么兜底
视图常用于报表口径封装,一旦出现 SUM(revenue) / SUM(clicks),某组 clicks 全为 0 或全为 NULL,查询直接中断,连 NULL 都不返回。这不是数据问题,是表达式没防住除零。
核心就一条:NULLIF() 必须包在分母上,且第二个参数必须是字面量 0,不是 0.0:
SUM(revenue) / NULLIF(SUM(clicks), 0)
注意三点:
-
NULLIF(SUM(clicks), 0)返回 NULL 时,整个除法结果就是 NULL,不会报错 - 如果业务要求“0点击时转化率显示为 0%”,再套一层
COALESCE(..., 0.0) - 务必乘
100.0而不是100,避免整数除法截断(如5 / 2 = 2)
权限没关紧,视图里的NULL处理全是白忙
视图本身不存数据,所有脱敏和 NULL 处理逻辑都在 SELECT 里实时计算——前提是用户只能查视图。如果还留着基表的 SELECT 权限,用户 SELECT * FROM users 一下,所有 IFNULL、CASE WHEN 全失效,敏感字段和 NULL 原样暴露。
建完视图后必须立刻执行:
REVOKE SELECT ON users FROM 'report_user'@'%';<br>GRANT SELECT ON user_view TO 'report_user'@'%';
容易被忽略的是:MySQL 8.0+ 的角色(ROLE)机制能批量管控,但很多人建完视图就停在这一步,忘了回收基表权限。Oracle 还要额外检查 EXPLAIN PLAN,确认执行路径没泄露基表名。










