一、函数概览
以下两个函数在数据处理中分别承担字符串截取和定位的核心功能,适用于MySQL、Oracle等主流数据库系统。
函数名 | 主要用途 | 适用场景 | 典型数据库支持 |
---|---|---|---|
substring_index() | 基于分隔符截取目标子字符串 | 地址解析、多层级文本分割 | MySQL |
instr() | 定位子字符串的起始位置 | 模糊查询、条件筛选、截取辅助 | Oracle/Hive/SQL |
二、substring_index()
函数详解
1. 语法与参数
sql
substring_index(string, sep, num)
- 参数说明
string
:待处理的原始字符串(字段或表达式)sep
:分隔符(如,
、.
等)num
:截取位置序号- 正数:从左向右计数
- 负数:从右向左计数
- 0:返回空字符串
2. 基础应用案例
案例1:提取域名前缀与后缀
sql
-- 截取第一个"."前的部分(如 "www")
SELECT substring_index('www.mysql.com', '.', 1); -- 结果:www
-- 截取最后一个"."后的部分(如 "com")
SELECT substring_index('www.mysql.com', '.', -1); -- 结果:com [1,3](@ref)
案例2:地址字段分层解析
假设表 student
中存在字段 address
存储省市区信息(如 "浙江省,杭州市,西湖区"
):
sql
-- 提取省份信息(第一个逗号前的内容)
SELECT
name,
substring_index(address, ',', 1) AS province
FROM student; [1](@ref)
案例3:处理动态前缀的日期字段
若日期字段 ctime
格式为 "13d 2022-02-01"
,需提取有效日期:
sql
SELECT
cast(substring_index(ctime, ' ', -1) AS date) AS dt
FROM data
WHERE substring_index(ctime, ' ', -1) >= '2022-03-04'; [1,5](@ref)
3. 高级嵌套用法
案例4:提取中间层级内容
从字符串 "aa,ddd,ccc"
中提取第二个分隔符前的部分:
sql
-- 先截取前两部分,再从结果中取最后一部分
SELECT
substring_index(substring_index('aa,ddd,ccc', ',', 2), ',', -1); -- 结果:ddd [3](@ref)
三、instr()
函数详解
1. 语法与参数
sql
instr(source_string, dest_string, [start_position], [nth_appearance])
- 参数说明
source_string
:源字符串dest_string
:目标子字符串start_position
(可选):起始搜索位置(默认1,负数表示从右向左)nth_appearance
(可选):指定第几次出现(默认1)
2. 基础应用案例
案例1:定位子字符串位置
sql
-- 查找第一个"l"的位置
SELECT instr('helloworld', 'l'); -- 结果:3 [7](@ref)
-- 查找第二次出现的"l"(从第4位开始)
SELECT instr('helloworld', 'l', 4, 2); -- 结果:9 [7](@ref)
案例2:模糊查询替代方案
替代 LIKE
实现模糊匹配:
sql
-- 查询包含"001"的用户记录
SELECT code, name
FROM staff
WHERE instr(code, '001') > 0; -- 等效于 code LIKE '%001%' [6,8](@ref)
案例3:动态截取字符串
结合 substr()
截取特定区间内容(如URL中参数值):
sql
-- 提取"id=123"中的ID值
SELECT
substr(url, instr(url, 'id=') + 3, 3) AS id
FROM links; [7](@ref)
3. 高级条件判断
案例4:分类标记
根据字段内容动态标记类别:
sql
SELECT
CASE
WHEN instr(description, '紧急') > 0 THEN '高危'
WHEN instr(description, '测试') > 0 THEN '低危'
ELSE '普通'
END AS risk_level
FROM tasks; [8](@ref)
四、联合应用场景
场景:解析动态结构日志
假设日志字段 log
格式为 "ERROR|2023-10-01 14:23|ServiceA|Connection timeout"
:
- 使用
instr()
定位分隔符sql
SELECT instr(log, '|', 1, 2) AS second_sep_pos FROM logs;
- 结合
substring_index()
提取时间戳sql
SELECT substring_index(substring_index(log, '|', 2), '|', -1) AS timestamp FROM logs; [3,7](@ref)
五、注意事项
函数 | 需规避的常见问题 |
---|---|
substring_index() | - 分隔符不存在时返回整个字符串 - 嵌套使用需注意截取顺序和边界条件 |
instr() | - 目标字符串不存在时返回0 - 起始位置为负数时实际索引仍从左计算 |
六、附录:函数对比速查表
特性 | substring_index() | instr() |
---|---|---|
核心功能 | 按分隔符截取子字符串 | 定位子字符串起始位置 |
返回值类型 | 字符串 | 整型(位置索引) |
典型应用 | 地址解析、层级数据拆分 | 模糊查询、动态截取辅助 |
跨库兼容性 | MySQL专用 | Oracle/Hive通用 |