直接拼接%会出错,因数值与字符串类型不兼容;MySQL需CONCAT(ROUND(val100,1), '%'),PostgreSQL需(ROUND(val100,1))::TEXT||'%',SQL Server推荐CONCAT(ROUND(val*100,2), '%')。

直接在 SQL 查询里加 % 符号拼接,绝大多数情况下会出错——因为数值字段不能直接和字符串用 + 或 || 连接,且不同数据库对类型隐式转换的容忍度差异极大。
MySQL 中用 CONCAT() + ROUND() 安全拼接
MySQL 不支持直接把数字和字符串相加(比如 score + '%' ),会强制转成数字导致结果为 0。必须显式转类型:
-
CONCAT(ROUND(score * 100, 1), '%'):先放大、四舍五入保留一位小数,再拼百分号 - 如果原始字段是小数(如
0.876),不乘 100 就直接拼,结果是"0.876%",通常不符合业务习惯 - 注意
ROUND()第二个参数为 0 时会丢掉小数点后所有位,比如ROUND(87.6, 0)→88,不是88.0
PostgreSQL 必须用 ::TEXT 显式转换
PostgreSQL 对类型更严格,|| 拼接时两边必须同为字符串,否则报错:operator does not exist: numeric || text:
-
(ROUND(score * 100, 1))::TEXT || '%'是安全写法 - 不能写成
score * 100 || '%',即使 score 是 numeric,乘法结果仍是 numeric,无法直接拼接 - 如果字段允许 NULL,记得套
COALESCE(..., 'N/A'),否则整行结果可能变 NULL
SQL Server 的 CONCAT() 更宽容但仍有陷阱
SQL Server 的 CONCAT() 会自动把非字符串参数转成字符串,看似省事,但容易掩盖精度问题:
-
CONCAT(ROUND(score * 100, 2), '%')可用,但若省略ROUND(),CONCAT(0.876 * 100, '%')可能输出"87.59999999999999%" -
CAST()和CONVERT()也能用,但语法更长,例如CONVERT(VARCHAR, ROUND(score * 100, 1)) + '%' - 旧版本(2012 之前)不支持
CONCAT(),只能用+拼接,此时必须手动CAST数值字段
真正麻烦的不是加个百分号,而是不同数据库对“数值→字符串”转换的默认行为不一致;哪怕同一 SQL 在 MySQL 和 PostgreSQL 里跑,一个返回 "87.6%",另一个可能报错或返回 "87.60000000000001%"——处理前务必确认源字段精度和目标数据库的舍入规则。

















