concat()遇任意null参数即返回null,非空字符串或跳过;concat_ws()自动跳过null且首参为分隔符,更安全;分隔符不可为null但可为空字符串;动态分隔符需用ifnull/coalesce兜底。

CONCAT() 遇任意 NULL 参数就返回 NULL
这是 MySQL CONCAT() 的硬性规则,不是 bug,而是设计行为:只要传入的任一参数值为 NULL,整个函数结果就是 NULL,不是空字符串 '',也不是跳过该字段继续拼接。
常见错误现象:
-
SELECT CONCAT('a', NULL, 'c')→ 返回NULL,不是'ac' - 在
WHERE中使用:WHERE CONCAT(title, content) LIKE '%xxx%',一旦title或content为NULL,整行被过滤掉(因为NULL LIKE '%xxx%'永远为FALSE) - 在
SELECT中显示为空白,但实际是NULL,容易误判为“数据丢了”
为什么 CONCAT_WS() 不会这样?
CONCAT_WS() 是专为规避这个问题设计的:它第一个参数是分隔符,后续所有 NULL 值会被自动忽略,只拼接非 NULL 字段。
使用场景和要点:
-
CONCAT_WS(' ', title, author, location):即使location是NULL,也能得到'足球新闻 张三' - 分隔符本身不能为
NULL,否则整条结果变NULL;但空字符串''合法,例如CONCAT_WS('', a, b)→'ab' - 不支持在分隔符位置写表达式,比如
CONCAT_WS(IFNULL(suffix, '-'), ...)会报错 —— 分隔符必须是字面量或确定值
什么时候必须用 IFNULL() 或 COALESCE()
当你需要给每个字段指定不同的兜底值(不只是空字符串),或者要兼容老版本 MySQL(NULL。
实操建议:
- 用
COALESCE(title, '')替代IFNULL(title, '')更通用(标准 SQL 支持) - 若要设默认值而非空串,比如作者为空时显示
'匿名':COALESCE(author, '匿名') - 注意嵌套深度:多个字段都要处理时,
CONCAT(COALESCE(a,''), COALESCE(b,''), COALESCE(c,''))写起来比CONCAT_WS()繁琐,也更易漏掉某个字段
跨数据库迁移时的陷阱
别以为 CONCAT() 行为一致 —— PostgreSQL 的 CONCAT() 虽也跳过 NULL,但 SQL Server 的 + 和 Oracle 的 || 都是“遇 NULL 即中断”,返回 NULL。
所以:
- 写可移植 SQL 时,不要裸用
CONCAT()或|| - 统一前置兜底:
CONCAT(COALESCE(str1, ''), COALESCE(str2, '')) - 如果只跑 MySQL,
CONCAT_WS()是最省心、最不易出错的选择
最容易被忽略的是:分隔符为 NULL 时,CONCAT_WS() 同样返回 NULL —— 这个边界条件在动态构造分隔符时尤其危险。










