SQL Server、Azure SQL、MySQL 8.0+、SQLite 3.29.0+原生支持LEFT/RIGHT;PostgreSQL默认不支持,需扩展或改用SUBSTRING;MySQL 5.7及更早版本不支持,须用SUBSTRING(col,1,n)替代。

能直接用 LEFT 和 RIGHT 的地方,就别绕弯写 SUBSTRING——但前提是确认你用的数据库版本真支持,且字段长度、空值、编码都可控。
哪些数据库能直接用 LEFT 和 RIGHT?
SQL Server、Azure SQL、MySQL 8.0+、SQLite 3.29.0+ 原生支持;PostgreSQL 默认不带,得装 pg_trgm 扩展或改用 SUBSTRING。MySQL 5.7 及更早版本会报错:FUNCTION LEFT does not exist,必须换成 SUBSTRING(col, 1, n) 或 SUBSTR(col, 1, n)。
验证方法很简单:
SELECT LEFT('test', 2), RIGHT('test', 2);如果报错,说明当前环境不支持,别硬套。
length 参数传错会怎样?
传负数或 NULL 是高频翻车点:
- SQL Server:直接报错
Invalid length parameter passed to the LEFT or SUBSTRING function - MySQL:返回空字符串
'',不报错但逻辑被静默破坏 - PostgreSQL(启用扩展后):同 SQL Server,报错
动态算长度时尤其危险,比如:
LEFT(email, CHARINDEX('@', email) - 1)若某行 email 不含 @,CHARINDEX 返回 0,第二参数变成 -1 —— SQL Server 立刻中断执行。稳妥写法是加 CASE 判断:
CASE WHEN CHARINDEX('@', email) > 0 THEN LEFT(email, CHARINDEX('@', email) - 1) ELSE NULL END截取结果长度不固定?那不是函数问题,是数据问题
RIGHT(col, 6) 遇到只有 4 位的值,照样返回那 4 位,不会补空格或报错。这在提取“身份证后四位”“设备码末六位”时极易埋雷。
实操建议:
- 先查分布:
SELECT col, LENGTH(col), RIGHT(col, 6) FROM t LIMIT 20; - 关键场景加长度校验:
WHERE LENGTH(col) >= 6 - 需要统一长度输出时,不用
LEFT/RIGHT补位,改用LPAD或RPAD(MySQL)或CONCAT拼接
对 NULL 和空字符串,LEFT/RIGHT 一律返回 NULL 或 '',不会抛异常,但后续 WHERE 或 JOIN 可能意外过滤掉整行。
字符集和多字节字符会影响结果吗?
只要连接层字符集配置正确(如 MySQL 客户端设为 utf8mb4),LEFT 和 RIGHT 都按“字符数”而非“字节数”截取,中文、emoji 不会截半。但如果你看到 RIGHT('订单-2024001', 3) 返回乱码或缺字,问题大概率出在客户端与服务端 collation 不一致,或者应用层用了错误的字符集连接数据库——这不是函数能解决的,得查连接配置。
真正容易被忽略的是:这些函数不校验输入合法性,也不做类型转换。一个 TEXT 类型字段在 SQL Server 中直接传给 LEFT 会失败,得先转成 VARCHAR(MAX);而 MySQL 对 TEXT 倒是宽容。不同引擎的隐式行为差异,得靠测试覆盖,不能凭经验猜。

















