数据库里要把多个字段拧成一根字符串,这事儿看上去简单,但不同数据库的写法差异还真不小。先说结论:不同数据库处理拼接的惯用手段、对 NULL 的容忍度、类型要求都不一样。跨库移植时,重点盯住 NULL 和类型转换,这是最容易翻车的地方。

MySQL里用 CONCAT() 拼接多个字段,NULL会让整列变NULL
MySQL 里最直接的方案是 CONCAT() 函数。但这个东西有个脾气——碰上 NULL 值,直接给你返回个 NULL,连带整列都玩完。比方说 CONCAT(first_name, ' ', last_name),只要 first_name 是 NULL,哪怕 last_name 再完整,结果也空空如也。
怎么破?把 NULL 提前换成空字符串就行:
- 用
IFNULL(col, '')或COALESCE(col, '')把每个可能为空的字段裹起来 - 代码写成这样:
CONCAT(IFNULL(first_name, ''), ' ', IFNULL(last_name, '')) - 另外一个坑是
CONCAT()不会自动帮你加空格或分隔符,这些得手动招呼进去
PostgreSQL必须用 || 操作符,且要显式处理NULL和类型
PostgreSQL 不走寻常路,不用函数,而是靠双竖线 ||。这个操作符说简单也简单,说麻烦也麻烦:遇到 NULL 依旧返回 NULL,而且对类型还挺挑剔——text 和 integer 不能直接拼接。
实操上的几个关键点:
- 用
COALESCE(col, '')处理NULL,这里别用IFNULL——PostgreSQL 不认识它 - 数字字段得先转文本:
COALESCE(col::text, '')或COALESCE(CAST(col AS text), '') - 完整示例:
COALESCE(first_name, '') || ' ' || COALESCE(last_name, '')
SQL Server的 + 号拼接容易报错,ISNULL() 是刚需
SQL Server 这边用的是 + 号。看似简单,坑却不少:只要有一个操作数是 NULL,结果就直接 NULL;要是字段是数值型,直接 + 字符串还会报类型转换错误。
稳妥写法要记牢:
- 所有字段都套上
ISNULL(col, '')——在这类场景下它比COALESCE略快 - 数值字段必须显式转字符串:
ISNULL(CAST(age AS VARCHAR), '') - 尽量别用
+连接混合类型,干脆直接用CONCAT()函数(SQL Server 2012+ 已支持,能自动转类型、自动忽略NULL)
跨数据库可移植写法?老老实实用 CONCAT() + COALESCE,但注意版本
那么问题来了,有没有一种写法能通吃各大数据库?答案是:可以折中,但没完全自由的方案。
COALESCE()在 MySQL、PostgreSQL、SQL Server 里都支持,是跨库的安全牌CONCAT()在 MySQL 和 SQL Server 里表现一致(自动忽略NULL),但在 PostgreSQL 里它压根不存在——得提前换个思路- 真要追求跨库,建议用标准 SQL 的
||拼接 +COALESCE,再配合应用层做类型转换。这比硬塞进一条 SQL 更可控、更清晰
字段一多、逻辑一复杂,拼接工作放到应用代码里反而更清爽,SQL 只管取出原始字段的值就行。
