从入门到实战详解MySQL中字符串处理函数完全指南
作者:tianyu234
在日常的数据库开发中,字符串处理绝对是最频繁的操作之一——拼接用户姓名、截取手机号后四位、格式化输出、替换敏感信息……如果没有字符串函数,这些看似简单的需求都会变得无比复杂。
今天,我们就来系统性地梳理MySQL中的字符串处理函数,每个都配上可直接运行的示例,让你看完就能用上。
一、字符串拼接:让散落的数据“粘”在一起
CONCAT —— 基础拼接
CONCAT() 用于将多个字符串连接成一个字符串。
-- 基础用法:拼接多个字符串
SELECT CONCAT('Hello', ' ', 'World');
-- 输出:Hello World
-- 拼接字段:把姓和名拼成全名
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users;
踩坑提醒:CONCAT() 的参数中只要有一个是 NULL,整个结果就是 NULL。比如 CONCAT('My', NULL, 'QL') 会返回 NULL。
CONCAT_WS —— 带分隔符的拼接
CONCAT_WS() 是 CONCAT 的升级版,第一个参数指定分隔符,后续参数是要拼接的内容。
-- 用 '-' 拼接日期
SELECT CONCAT_WS('-', '2026', '08', '06');
-- 输出:2026-08-06
-- 拼接带格式的电话号码
SELECT CONCAT_WS('-', LEFT(phone, 3), SUBSTRING(phone, 4, 4), RIGHT(phone, 4))
AS formatted_phone FROM users;
-- 例如:13812345678 → 138-1234-5678
CONCAT_WS() 会自动忽略 NULL 值,比 CONCAT() 更安全。
二、字符串截取:精准“剪裁”你需要的部分
SUBSTRING —— 按位置截取
SUBSTRING(str, pos, len) 从指定位置开始截取指定长度的子串。
-- 从第1位开始截取5个字符
SELECT SUBSTRING('Hello World', 1, 5);
-- 输出:Hello
-- 提取邮箱域名(@之后的部分)
SELECT email, SUBSTRING(email, INSTR(email, '@') + 1) AS domain FROM users;
-- 输出:example@gmail.com → gmail.com
LEFT 和 RIGHT —— 从两端截取
SELECT LEFT('Hello World', 5); -- 输出:Hello
SELECT RIGHT('Hello World', 5); -- 输出:World
SUBSTRING_INDEX —— 按分隔符截取
按分隔符截取字符串的某一部分,非常适合处理 CSV 格式的数据。
-- 取第一个逗号之前的内容
SELECT SUBSTRING_INDEX('apple,banana,orange', ',', 1);
-- 输出:apple
-- 取最后一个逗号之后的内容(负数表示从右往左数)
SELECT SUBSTRING_INDEX('apple,banana,orange', ',', -1);
-- 输出:orange
三、字符串替换:修改内容的“橡皮擦”
REPLACE —— 全局替换
REPLACE(str, from_str, to_str) 将字符串中所有出现的 from_str 替换为 to_str。
-- 基础替换
SELECT REPLACE('Hello World', 'World', 'MySQL');
-- 输出:Hello MySQL
-- 替换邮箱域名
SELECT REPLACE(email, '@old.com', '@new.com') AS new_email FROM users;
-- 多个匹配全部替换
SELECT REPLACE('apple banana apple', 'apple', 'orange');
-- 输出:orange banana orange
INSERT —— 指定位置替换
INSERT(str, pos, len, newstr) 从 pos 位置开始,将长度为 len 的子串替换为 newstr。
-- 从第3位开始,替换4个字符
SELECT INSERT('Quadratic', 3, 4, 'What');
-- 输出:QuWhattic
四、字符串查找:在大段文本中“定位”目标
INSTR 和 LOCATE —— 查找子串位置
两者功能相同,只是参数顺序不同。
-- INSTR(str, substr):先写字符串,再写子串
SELECT INSTR('Hello World', 'World');
-- 输出:7
-- LOCATE(substr, str):先写子串,再写字符串
SELECT LOCATE('World', 'Hello World');
-- 输出:7
-- 实战:查找名字中包含"李"的用户
SELECT * FROM users WHERE INSTR(name, '李') > 0;
五、大小写转换:统一文本格式
SELECT UPPER('hello'); -- 输出:HELLO
SELECT LOWER('HELLO'); -- 输出:hello
UPPER() 和 UCASE() 等价,LOWER() 和 LCASE() 等价。
六、去除空格:让数据更“干净”
SELECT TRIM(' hello '); -- 输出:hello(去除两端空格)
SELECT LTRIM(' hello'); -- 输出:hello(去除左侧空格)
SELECT RTRIM('hello '); -- 输出:hello(去除右侧空格)
TRIM() 只去除字符串头部和尾部的空格,中间的空格不会被删除。
七、字符串填充:让数据“对齐”
LPAD 和 RPAD —— 左右填充
-- 左填充:用 '0' 在左边填充到总长度5
SELECT LPAD('1', 5, '0');
-- 输出:00001
-- 右填充:用 '*' 在右边填充到总长度10
SELECT RPAD('Name', 10, '*');
-- 输出:Name******
-- 实战:学号统一补足6位
UPDATE student SET sn = LPAD(sn, 6, '0');
八、字符串长度:区分“字符数”和“字节数”
SELECT LENGTH('MySQL'); -- 输出:5(字节数)
SELECT CHAR_LENGTH('数据库'); -- 输出:3(字符数,一个汉字算1个字符)
在 UTF-8 编码下,一个汉字占 3 个字节,一个英文字母占 1 个字节。
九、其他实用函数
REVERSE —— 反转字符串
SELECT REVERSE('Hello');
-- 输出:olleH
REPEAT —— 重复字符串
SELECT REPEAT('Ha', 3);
-- 输出:HaHaHa
ASCII —— 获取首字符的 ASCII 码
SELECT ASCII('a'); -- 输出:97
SELECT ASCII('ab'); -- 输出:97(只返回第一个字符)
十、集合与列表处理:FIND_IN_SET 家族
这一组函数专门用来处理逗号分隔的字符串列表(CSV格式),在标签系统、权限控制、多选字段和自定义排序中极其好用。
FIND_IN_SET —— 在逗号列表中查找元素位置
FIND_IN_SET(str, strlist) 返回子串在逗号分隔列表中的位置索引(从1开始),找不到则返回0。
-- 基础查找
SELECT FIND_IN_SET('b', 'a,b,c,d'); -- 输出:2
SELECT FIND_IN_SET('e', 'a,b,c,d'); -- 输出:0
-- 实战:查询拥有“管理员”角色的用户(角色字段存的是 '编辑,管理员,审核')
SELECT * FROM users WHERE FIND_IN_SET('管理员', roles) > 0;
-- 实战:按给定的ID顺序查询(配合 ORDER BY)
SELECT * FROM products
WHERE FIND_IN_SET(id, '3,1,5,2') > 0
ORDER BY FIND_IN_SET(id, '3,1,5,2');
-- 结果将按 3 → 1 → 5 → 2 的顺序排列
特别注意:FIND_IN_SET 的第二个参数必须是一个纯逗号分隔的字符串,不能包含空格(如 'a, b, c' 会查找失败)。如果想忽略空格,需先结合 REPLACE 处理。
ELT —— 按索引取元素
ELT(N, str1, str2, ...) 返回第 N 个位置的字符串。非常适合做枚举值的美化映射。
-- 取第2个元素 SELECT ELT(2, 'Spring', 'Summer', 'Autumn', 'Winter'); -- 输出:Summer -- 实战:将数字状态码转为中文描述(1-待支付, 2-已支付, 3-已取消) SELECT order_id, ELT(status, '待支付', '已支付', '已取消') AS status_desc FROM orders;
FIELD —— 按值查找位置(自定义排序神器)
FIELD(str, str1, str2, ...) 返回 str 在后面列表中的首次出现位置(从1开始),找不到返回0。它与 FIND_IN_SET 功能互补,但参数形式不同(一个是逗号字符串,一个是枚举列表)。
-- 基础查找
SELECT FIELD('orange', 'apple', 'banana', 'orange', 'grape');
-- 输出:3
-- 🔥 最强实战:自定义排序(将状态按 待支付 → 已支付 → 已取消 的顺序排列)
SELECT * FROM orders
ORDER BY FIELD(status, 'pending', 'paid', 'cancelled');
-- 注意:不在列表中的 status 会排在最前面(因为返回0),可用此特性做兜底
MAKE_SET —— 按位掩码组合元素
MAKE_SET(bits, str1, str2, ...) 根据 bits 的二进制位,挑选对应位置的字符串并用逗号拼接返回。
-- bits=3(二进制 011),取第1位和第2位 SELECT MAKE_SET(3, 'A', 'B', 'C', 'D'); -- 输出:A,B (因为 3 = 1+2,代表取第1个和第2个) -- bits=5(二进制 101),取第1位和第3位 SELECT MAKE_SET(5, 'A', 'B', 'C', 'D'); -- 输出:A,C (因为 5 = 1+4) -- 实战:通过权限位快速生成权限标签(1-读, 2-写, 4-执行) SELECT user_id, MAKE_SET(permission_bit, '读权限', '写权限', '执行权限') AS permissions FROM user_roles; -- 当 permission_bit = 6 时(110),输出:写权限,执行权限
本节函数速查对比:
| 函数 | 输入 | 输出 | 典型场景 |
|---|---|---|---|
FIND_IN_SET | (值, ‘逗号列表’) | 位置索引 | WHERE 条件判断 |
FIELD | (值, 值1, 值2, …) | 位置索引 | ORDER BY 自定义排序 |
ELT | (索引, 值1, 值2, …) | 对应值 | 枚举数字转文字 |
MAKE_SET | (位掩码, 值1, 值2, …) | 拼接后的逗号列表 | 权限标签组合 |
十一、综合实战案例
案例1:格式化用户信息
SELECT CONCAT(first_name, ' ', last_name, ' <', email, '>') AS full_info FROM users; -- 输出:张三 <zhangsan@example.com>
案例2:脱敏处理(隐藏邮箱部分信息)
SELECT CONCAT(LEFT(email, 3), '***', SUBSTRING(email, INSTR(email, '@'))) AS masked_email FROM users; -- 输出:exa***@gmail.com
案例3:统计用户名长度并排序
SELECT username, LENGTH(username) AS username_length FROM users ORDER BY username_length DESC;
案例4:生成固定格式的订单号
SELECT CONCAT('ORD', DATE_FORMAT(NOW(), '%Y%m%d'), LPAD(order_seq, 4, '0'))
AS order_no FROM orders;
-- 输出:ORD202608060001
案例5:标签检索与自定义排序(新增)
-- 查询同时包含 "科技" 和 "金融" 标签的文章(tags存为 '科技,金融,AI')
SELECT * FROM articles
WHERE FIND_IN_SET('科技', tags) > 0
AND FIND_IN_SET('金融', tags) > 0;
-- 将文章按指定的优先级排序(置顶推荐)
SELECT * FROM articles
ORDER BY FIELD(id, 1003, 1007, 1001, 1005) DESC, created_at DESC;
总结
MySQL 的字符串处理函数种类丰富、功能强大。掌握好这些函数,能让你的 SQL 语句更加简洁高效。建议收藏本文,在实际开发中遇到字符串处理需求时,随时查阅对照。
快速索引:
| 功能分类 | 核心函数 |
|---|---|
| 拼接 | CONCAT, CONCAT_WS |
| 截取 | SUBSTRING, LEFT, RIGHT, SUBSTRING_INDEX |
| 替换 | REPLACE, INSERT |
| 查找 | INSTR, LOCATE |
| 集合/列表处理 | FIND_IN_SET, FIELD, ELT, MAKE_SET |
| 大小写 | UPPER, LOWER |
| 去空格 | TRIM, LTRIM, RTRIM |
| 填充 | LPAD, RPAD |
| 长度 | LENGTH, CHAR_LENGTH |
| 其他 | REVERSE, REPEAT, ASCII |
以上就是从入门到实战详解MySQL中字符串处理函数完全指南的详细内容,更多关于MySQL字符串处理的资料请关注脚本之家其它相关文章!
