在SQL的实际开发工作中,处理字符串数据是极为常见的需求,很多时候我们需要从一段完整的字符串里提取出符合要求的特定部分,比如从用户提交的完整地址中拆分出省份信息,或者从接口返回的拼接字符串里取出核心参数。SUBSTRING函数负责完成字符串的截取动作,INSTR函数则用来确定目标字符的位置,将二者结合使用可以覆盖绝大多数复杂的截取场景。

SUBSTRING函数基础用法
SUBSTRING函数的作用是从指定字符串中截取从某个起始位置开始,长度为指定值的子字符串,不同数据库的参数格式略有差异,但核心逻辑一致。
以MySQL为例,SUBSTRING函数的语法为:
-- MySQL中SUBSTRING语法,string为原字符串,start为起始位置(从1开始计数),length为截取长度 SUBSTRING(string, start, length)
如果省略length参数,则会截取从start位置到字符串末尾的所有内容:
-- 截取从位置2开始到末尾的内容
SELECT SUBSTRING('hello_world', 2); -- 结果为ello_world
INSTR函数基础用法
INSTR函数用于返回指定子字符串在原字符串中第一次出现的位置,同样不同数据库的参数顺序有区别。
MySQL中INSTR函数的语法为:
-- 返回substr在str中第一次出现的位置,未找到返回0 INSTR(str, substr)
示例演示:
-- 查找下划线在字符串中的位置
SELECT INSTR('hello_world', '_'); -- 结果为6
在Oracle数据库中,INSTR函数的参数顺序为INSTR(str, substr, start, occurrence),其中start是开始查找的位置,occurrence是指定第几次出现,默认都是1。
SUBSTRING与INSTR结合截取特定部分
结合两个函数的核心逻辑是:先用INSTR找到目标分隔符的位置,再把这个位置作为SUBSTRING的起始或结束参数,实现精准截取。
场景1:截取第一个分隔符之前的内容
比如原字符串是user_123_login,需要截取第一个下划线之前的内容user:
-- MySQL示例,INSTR找到下划线位置,减1作为截取长度
SELECT SUBSTRING('user_123_login', 1, INSTR('user_123_login', '_') - 1) AS result;
-- 结果为user
场景2:截取两个分隔符之间的内容
同样以user_123_login为例,需要截取两个下划线之间的123:
-- 先找到第一个下划线位置,再找到第二个下划线位置,计算截取起始和长度
SELECT SUBSTRING(
'user_123_login',
INSTR('user_123_login', '_') + 1,
INSTR('user_123_login', '_', INSTR('user_123_login', '_') + 1) - INSTR('user_123_login', '_') - 1
) AS result;
-- 结果为123
场景3:截取最后一个分隔符之后的内容
要截取user_123_login中最后一个下划线之后的login,需要先找到最后一个下划线的位置:
-- MySQL中可以用LENGTH和REPLACE计算最后一个下划线位置
SELECT SUBSTRING(
'user_123_login',
INSTR('user_123_login', '_', LENGTH('user_123_login') - LENGTH(REPLACE('user_123_login', '_', ''))) + 1
) AS result;
-- 结果为login
不同数据库的适配说明
不同数据库的字符串函数存在差异,以下是常见数据库的适配方式:
| 数据库类型 | INSTR函数差异 | SUBSTRING函数差异 |
|---|---|---|
| MySQL | 参数为INSTR(str, substr) | 支持SUBSTRING(str, start, length) |
| Oracle | 参数为INSTR(str, substr, start, occurrence) | 支持SUBSTR(str, start, length),注意函数名是SUBSTR |
| SQL Server | 使用CHARINDEX(substr, str)替代INSTR | 支持SUBSTRING(str, start, length) |
SQL Server中截取两个下划线之间内容的示例:
-- SQL Server中用CHARINDEX替代INSTR
SELECT SUBSTRING(
'user_123_login',
CHARINDEX('_', 'user_123_login') + 1,
CHARINDEX('_', 'user_123_login', CHARINDEX('_', 'user_123_login') + 1) - CHARINDEX('_', 'user_123_login') - 1
) AS result;
-- 结果为123
注意事项
- INSTR函数未找到目标字符时返回0,此时如果直接用作SUBSTRING的参数可能会导致截取结果异常,建议提前做判断处理。
- 字符串位置计数在不同数据库中可能从0或者1开始,使用时需要确认对应数据库的规则,避免位置计算错误。
- 如果原字符串中不存在对应的分隔符,需要增加条件判断,比如用CASE WHEN语句处理异常场景,避免SQL执行报错。
实际使用中可以根据具体的字符串格式和截取需求,灵活调整INSTR的查找参数和SUBSTRING的起始、长度参数,实现更精准的字符串处理效果。