MySQL的SUBSTRING(str, pos, len)从1开始计位、支持负pos倒取、len越界自动截尾;PostgreSQL需用SUBSTRING(str FROM pos FOR len)或正则;SQL Server不支持负pos且len为负报错;跨库推荐LEFT/RIGHT函数。

MySQL里用SUBSTRING截字符串,参数顺序容易搞反
MySQL的SUBSTRING(也叫SUBSTR)是三参数函数:SUBSTRING(str, pos, len),但很多人误以为是(str, start, end)——它没有“结束位置”,只有“从哪开始、取几个字符”。
常见错误现象:SUBSTRING('hello', 2, 4) 返回 'ello',不是 'ell';因为从第2位(e)开始,取4个字符,刚好到末尾。
- 位置从1开始计数,不是0(
SUBSTRING('abc', 0, 1)返回空字符串,不是'a') - 如果
len超出剩余长度,自动截到末尾,不会报错 -
pos为负数时,从末尾倒数:SUBSTRING('world', -3, 2)→'rl'
PostgreSQL要用SUBSTRING加正则或位置语法
PostgreSQL不支持MySQL那种三参数形式。直接写SUBSTRING('abcde', 2, 3)会报错:function substring(unknown, integer, integer) does not exist。
必须显式指定类型或换语法:
- 位置截取:
SUBSTRING('abcde' FROM 2 FOR 3)→'bcd' - 正则提取:
SUBSTRING('price: $123.45' FROM '\$([0-9.]+)')→'123.45' - 省略
FOR时默认取到末尾:SUBSTRING('hello' FROM 3)→'llo'
SQL Server用SUBSTRING但位置从1起且不支持负数
SQL Server的SUBSTRING(str, start, length)和MySQL形似,但关键限制是:不支持负数start,也不会静默处理越界——start超出字符串长度时返回空字符串,length为负直接报错Argument data type int is invalid for argument 3 of substring function.
-
SUBSTRING('test', 10, 2)→ 空字符串(不是报错) -
SUBSTRING('test', 1, 100)→ 安全返回'test' - 想实现MySQL的“倒取”,得配合
LEN():SUBSTRING(col, LEN(col)-2+1, 3)
跨数据库可移植写法?别硬套SUBSTRING,优先考虑LEFT/RIGHT
如果只是取前N位或后N位,LEFT(str, n)和RIGHT(str, n)在MySQL、PostgreSQL(需pg_trgm扩展或9.6+)、SQL Server都支持,语义更直白,出错率低。
但要注意:
- PostgreSQL原生不带
LEFT/RIGHT,9.6+才内置;旧版本得用SUBSTRING(str FROM 1 FOR n) -
LEFT(col, 5)比SUBSTRING(col, 1, 5)少一个参数维度,不容易漏写或错序 - 涉及动态起始位置(比如找某个分隔符之后的内容),还是绕不开
SUBSTRING配合POSITION或CHARINDEX
真正麻烦的从来不是函数怎么写,而是不同数据库对“位置从0还是1开始”“负数含义”“越界行为”的隐式约定——查文档前先确认你连的是哪个引擎。










