字符串函数
1. CONCAT 函数
Section titled “1. CONCAT 函数”在 MySQL 开发中,常常需要把多个字段或文字拼接成一个完整的字符串,比如展示用户完整姓名、地址,或者把多个业务信息合并输出。这时候 CONCAT 就派上用场了。
1.1. CONCAT 的语法
Section titled “1.1. CONCAT 的语法”CONCAT(str1, str2, ...);-
功能:将多个字符串拼接成一个字符串
-
特点:==如果其中任何一个参数为
NULL,整个结果会返回NULL==
CONCAT_WS拼接参数时,自动跳过NULL值,只拼接非NULL的部分。
1.2. CONCAT 的例子
Section titled “1.2. CONCAT 的例子”1.2.1. 简单拼接
Section titled “1.2.1. 简单拼接”SELECT CONCAT('Hello', ' ', 'World') AS result;-- 结果:Hello World1.2.2. 多列拼接
Section titled “1.2.2. 多列拼接”假设有一张房屋表,包含楼盘、楼栋、单元、房号:
SELECT CONCAT(fbv.villa_name, fbvb.building_name, fbvh.unit, fbvh.room_num) AS housingInfoFROM house;-
结果示例:
“绿谷小区A栋2单元301” -
场景:把分散的列整合成一个业务可读字段,便于展示或导出
1.3. 业务场景
Section titled “1.3. 业务场景”-
信息展示:姓名 + 工号,或者完整地址
-
日志记录:把操作人、时间、动作拼成一条完整日志
-
生成唯一标识:组合多个字段形成业务唯一 key
2. LEFT 函数
Section titled “2. LEFT 函数”在日常开发中,经常需要 截取字符串的一部分。比如脱敏处理手机号、身份证号,或者只取名字的前几个字符。MySQL 提供了 LEFT 函数来方便地实现这一功能。
2.1. LEFT 的语法
Section titled “2.1. LEFT 的语法”LEFT(str, length);-
功能:返回字符串左边的
length个字符 -
特点:
-
如果
length大于字符串长度,会返回整个字符串 -
可用于数据脱敏、字段截取等场景
-
2.2. LEFT 的例子
Section titled “2.2. LEFT 的例子”2.2.1. 基础用法
Section titled “2.2.1. 基础用法”SELECT LEFT('abcdefg', 3) AS result;-- 结果:abc2.2.2. 数据脱敏
Section titled “2.2.2. 数据脱敏”假设有一张申请人表,需要显示 姓名 + 身份证前 9 位 + 脱敏:
SELECT CONCAT(bfm.name, LEFT(bfm.identity_number, 9), '****') AS applicantInfoFROM applicant;-
结果示例:
“张三123456789****” -
场景:保护用户隐私,只显示部分信息
2.3. 业务场景
Section titled “2.3. 业务场景”-
数据脱敏:身份证号、手机号、邮箱
-
字段截取:名字、编号、编码前缀
-
报告或展示:截取前几位生成简短标签
3. CONCAT_WS 函数
Section titled “3. CONCAT_WS 函数”在地址、路径、标签等用分隔符拼接的场景里很常用;与 CONCAT 最大区别是:会自动忽略 NULL 参数。
3.1. CONCAT_WS 的语法
Section titled “3.1. CONCAT_WS 的语法”CONCAT_WS(separator, str1, str2, ...);-
功能:用指定
separator把多个字符串连接起来 -
特点:自动跳过
NULL;但不会跳过空字符串'' -
对比:
CONCAT只拼接,无分隔符,且任一参数NULL会得到NULL
3.2. CONCAT_WS 的例子
Section titled “3.2. CONCAT_WS 的例子”3.2.1. 忽略 NULL 的地址拼接
Section titled “3.2.1. 忽略 NULL 的地址拼接”SELECT CONCAT_WS('', bfm.residence_place_province, bfm.residence_place_city, bfm.residence_place_district, bfm.residence_place_subdistrict, bfm.residence_place_community, bfm.residence_place_address ) AS `地区`FROM bzdx_family_member bfm;3.2.2. 用分隔符拼接成“省/市/区/…”样式
Section titled “3.2.2. 用分隔符拼接成“省/市/区/…”样式”SELECT CONCAT_WS('/', bfm.residence_place_province, bfm.residence_place_city, bfm.residence_place_district, bfm.residence_place_subdistrict, bfm.residence_place_community, bfm.residence_place_address ) AS `地区路径`FROM bzdx_family_member bfm;3.3. 业务场景
Section titled “3.3. 业务场景”-
地址/面包屑:省/市/区/街道/门牌
-
标签/多值字段:用逗号或竖线连接
-
日志/提示:只拼接存在的非空信息,避免多余分隔符
4. LOWER 函数
Section titled “4. LOWER 函数”把字符串转为小写,便于规范化、去重或不区分大小写比较。
4.1. LOWER 的语法
Section titled “4.1. LOWER 的语法”LOWER(str); -- 同义:LCASE(str)-
功能:返回小写版本
-
特点:与字符集/排序规则有关;多数场景直接可用
4.2. LOWER 的例子
Section titled “4.2. LOWER 的例子”SELECT LOWER(bfm.source_system) AS `数据来源`FROM bzdx_family_member bfm;4.3. 业务场景
Section titled “4.3. 业务场景”-
统一存储格式(如邮箱、系统标识)
-
不区分大小写的查重/比较(也可结合
COLLATE)
5. UPPER 函数
Section titled “5. UPPER 函数”把字符串转为大写,常见于编码、编号统一。
5.1. UPPER 的语法
Section titled “5.1. UPPER 的语法”UPPER(str); -- 同义:UCASE(str)5.2. UPPER 的例子
Section titled “5.2. UPPER 的例子”SELECT UPPER(bfm.source_system) AS `数据来源`FROM bzdx_family_member bfm;5.3. 业务场景
Section titled “5.3. 业务场景”-
统一编号/编码大小写
-
展示层面强调可读性(如国家/区域代码)
6. LPAD 函数
Section titled “6. LPAD 函数”左侧填充到指定长度;若目标长度小于原串,会发生左侧截断。
6.1. LPAD 的语法
Section titled “6.1. LPAD 的语法”LPAD(str, len, padstr);-
功能:将
str用padstr在左侧补齐到len长度 -
特点:若
len<str长度,则返回左侧被截断后的字符串
LPAD/RPAD/SUBSTRING的len在字符语境下是按字符长度处理(常见 UTF-8 配置即可正确按字符计算)。
6.2. LPAD 的例子
Section titled “6.2. LPAD 的例子”SELECT LPAD(bfm.name, 18, '*') AS `凭证`FROM bzdx_family_member bfm;说明:以上是“凑满 18 位”的展示技巧;若要脱敏(显示最后 N 位,其余用
*左填充),可用:
SELECT LPAD(RIGHT(bfm.name, 1), CHAR_LENGTH(bfm.name), '*') AS `姓名脱敏`FROM bzdx_family_member bfm;6.3. 业务场景
Section titled “6.3. 业务场景”-
固定宽度展示(对齐输出、报表)
-
掩码/占位效果(结合
LEFT/RIGHT)
7. RPAD 函数
Section titled “7. RPAD 函数”右侧填充到指定长度;若目标长度小于原串,会发生右侧截断。
7.1. RPAD 的语法
Section titled “7.1. RPAD 的语法”RPAD(str, len, padstr);
LPAD/RPAD/SUBSTRING的len在字符语境下是按字符长度处理(常见 UTF-8 配置即可正确按字符计算)。
7.2. RPAD 的例子
Section titled “7.2. RPAD 的例子”SELECT RPAD(bfm.name, 18, '*') AS `凭证`FROM bzdx_family_member bfm;脱敏(保留首字,后面用
*补齐到原长度):
SELECT CONCAT(LEFT(bfm.name, 1), RPAD('', GREATEST(CHAR_LENGTH(bfm.name)-1,0), '*')) AS `姓名脱敏`FROM bzdx_family_member bfm;7.3. 业务场景
Section titled “7.3. 业务场景”-
报表定宽列、打印对齐
-
右侧补全占位符
8. TRIM / LTRIM / RTRIM 函数
Section titled “8. TRIM / LTRIM / RTRIM 函数”用于去除空格或指定字符。TRIM 更灵活,LTRIM/RTRIM 专注去左/右空格。
8.1. 语法
Section titled “8.1. 语法”TRIM(str); -- 去两端空格TRIM([BOTH | LEADING | TRAILING] remstr FROM str); -- 去两端/左/右 指定字符 remstrLTRIM(str); -- 去左空格RTRIM(str); -- 去右空格8.2. 例子
Section titled “8.2. 例子”SELECT TRIM(BOTH '-' FROM bfm.identity_number) AS `证件号`FROM bzdx_family_member bfm;去除证件号两边的
-。
8.3. 业务场景 / 注意
Section titled “8.3. 业务场景 / 注意”-
清洗脏数据(输入多余空格、分隔符)
-
LTRIM/RTRIM只处理空格;如需去除特定字符,优先用TRIM(... FROM ...)
9. SUBSTRING 函数
Section titled “9. SUBSTRING 函数”从指定位置截取子串;支持可选长度以及负索引(从末尾倒数)。
9.1. SUBSTRING 的语法
Section titled “9.1. SUBSTRING 的语法”SUBSTRING(str, pos); -- 从 pos 开始到结尾SUBSTRING(str, pos, len); -- 从 pos 开始截取 len 个字符-- 同义:SUBSTR(str, pos, len)
-- 说明:pos 从 1 开始;pos 为负数表示从末尾倒数的位置开始
LPAD/RPAD/SUBSTRING的len在字符语境下是按字符长度处理(常见 UTF-8 配置即可正确按字符计算)。
9.2. SUBSTRING 的例子
Section titled “9.2. SUBSTRING 的例子”9.2.1. 取后证件号尾号 4 位
Section titled “9.2.1. 取后证件号尾号 4 位”SELECT SUBSTRING(bfm.identity_number, -4) AS `证件尾号`FROM bzdx_family_member bfm;9.2.2. 组合脱敏(首字 + * * (长度-1))
Section titled “9.2.2. 组合脱敏(首字 + * * (长度-1))”SELECT CONCAT( SUBSTRING(bfm.name, 1, 1), RPAD('', GREATEST(CHAR_LENGTH(bfm.name)-1,0), '*') ) AS `姓名脱敏`FROM bzdx_family_member bfm;9.3. 业务场景
Section titled “9.3. 业务场景”-
编码/编号分段提取(前缀、批次号)
-
隐私脱敏(固定保留/隐藏规则)
10. CHAR_LENGTH 函数
Section titled “10. CHAR_LENGTH 函数”用于按字符个数统计字符串长度。对包含中文、emoji 等多字节字符时尤为准确。
10.1. CHAR_LENGTH 的语法
Section titled “10.1. CHAR_LENGTH 的语法”CHAR_LENGTH(str); -- 同义:CHARACTER_LENGTH(str)-
功能:返回字符串所含字符的个数
-
特点:与字符集相关;多字节字符(如中文、emoji)计为 1 个字符
-
返回:
NULL传入则返回NULL
10.2. CHAR_LENGTH 的例子
Section titled “10.2. CHAR_LENGTH 的例子”10.2.1. 基础对比
Section titled “10.2.1. 基础对比”SELECT CHAR_LENGTH('abc') AS c1, -- 3 CHAR_LENGTH('中文') AS c2, -- 2 CHAR_LENGTH('😊') AS c3; -- 1(emoji)10.2.2. 校验证件号长度(按字符)
Section titled “10.2.2. 校验证件号长度(按字符)”SELECT bfm.identity_number, CHAR_LENGTH(bfm.identity_number) AS len_charFROM bzdx_family_member bfmWHERE CHAR_LENGTH(bfm.identity_number) NOT IN (15, 18);10.2.3. 脱敏保留首字符 + 其余用 *
Section titled “10.2.3. 脱敏保留首字符 + 其余用 *”SELECT CONCAT( SUBSTRING(bfm.name, 1, 1), RPAD('', GREATEST(CHAR_LENGTH(bfm.name)-1, 0), '*')) AS `姓名脱敏`FROM bzdx_family_member bfm;10.3. 业务场景
Section titled “10.3. 业务场景”-
长度校验:账号、证件号、手机号等(按“字符”而非字节)
-
UI 截断:限制标题/昵称长度,避免多字节字符被误判
-
脱敏/切片:与
SUBSTRING/LPAD/RPAD联合使用
11. LENGTH 函数
Section titled “11. LENGTH 函数”用于按字节数统计字符串长度。适合与存储、编码、网络传输等“字节级”逻辑相关的场景。
11.1. LENGTH 的语法
Section titled “11.1. LENGTH 的语法”LENGTH(str); -- 同义:OCTET_LENGTH(str)-
功能:返回字符串的字节长度
-
特点:与字符集密切相关(如
utf8mb4下:中文通常 3 字节,emoji 多为 4 字节) -
返回:
NULL传入则返回NULL
11.2. LENGTH 的例子
Section titled “11.2. LENGTH 的例子”11.2.1. 基础对比(以 utf8mb4 为例)
Section titled “11.2.1. 基础对比(以 utf8mb4 为例)”SELECT LENGTH('abc') AS b1, -- 3 LENGTH('中文') AS b2, -- 6(每个中文 3 字节) LENGTH('😊') AS b3; -- 4(emoji 常为 4 字节)11.2.2. 评估存储/报文体量(按字节)
Section titled “11.2.2. 评估存储/报文体量(按字节)”SELECT bfm.name, LENGTH(bfm.name) AS bytes_utf8mb4FROM bzdx_family_member bfmORDER BY LENGTH(bfm.name) DESCLIMIT 10;11.2.3. 截断到指定字节
Section titled “11.2.3. 截断到指定字节”谨慎!按字节截断容易把多字节字符“截断坏”,除非你非常确定数据是单字节编码。
-- 示例:仅演示思路,不建议对多字节字符集直接这样做SELECT SUBSTRING(bfm.remark, 1, 100) AS remark_truncated_bytesFROM bzdx_family_member bfm;11.3. 业务场景
Section titled “11.3. 业务场景”-
容量/配额:字段存储体积估算、导出大小控制
-
接口/协议:按字节限制的报文、缓存键长度等
-
兼容性检查:迁移到定长/字节敏感系统时的预检
12. CHAR_LENGTH & LENGTH 两者选择与注意事项
Section titled “12. CHAR_LENGTH & LENGTH 两者选择与注意事项”12.1. 如何选择
Section titled “12.1. 如何选择”-
展示/校验/脱敏:用
CHAR_LENGTH(按字符更贴近“人类视角”)。 -
存储/传输/配额:用
LENGTH(按字节更贴近“机器视角”)。
12.2. 字符集差异
Section titled “12.2. 字符集差异”-
在
utf8mb4下:大部分中文 ≈ 3 字节;常见 emoji ≈ 4 字节。 -
不同字符集会影响
LENGTH的结果,但不影响CHAR_LENGTH的“字符数”。
12.3. 空格与类型
Section titled “12.3. 空格与类型”-
VARCHAR中尾随空格是实际存储的,CHAR_LENGTH('a ')与LENGTH('a ')通常都算上空格。 -
对
CHAR(N)类型,MySQL 在比较时会忽略尾随空格;如需“目视长度”,建议RTRIM后再计算:
SELECT CHAR_LENGTH(RTRIM(col)), LENGTH(RTRIM(col)) FROM t;12.4. NULL 行为
Section titled “12.4. NULL 行为”-
CHAR_LENGTH(NULL)与LENGTH(NULL)都返回NULL。 -
若需把
NULL当作空串参与计算,可用IFNULL(col, '')。
12.5. 索引与性能
Section titled “12.5. 索引与性能”-
在
WHERE中对列应用函数(如WHERE CHAR_LENGTH(col)=…)通常会失去索引利用。 -
可考虑:
-
通过生成列(
GENERATED COLUMN)保存长度并建索引; -
或在写入时冗余存储长度字段;
-
或把过滤条件改写为能利用索引的形式。
-