MySQL 中处理字符串字段时,经常会遇到只需要提取开头部分内容的场景,例如获取手机号前3位、订单号前缀、身份证号码前6位、文件名的前缀,或者截取商品编码的固定长度。对于这类需求,LEFT() 函数是非常直接、易读的解决方案。
一、MySQL LEFT函数基本语法
LEFT() 用于从字符串左侧开始截取指定长度的字符。
基本语法如下:
SQLLEFT(str, len)
参数含义:
-
str:需要截取的字符串,也可以是表中的字段。 -
len:需要截取的字符数量。
例如:
SQLSELECT LEFT('ABCDEFG', 3);
查询结果为:
ABC
这里从字符串最左侧开始,提取了3个字符。
如果需要提取字段的前几位,只需要将字符串参数替换成字段名即可:
SQLSELECT LEFT(username, 3) FROM users;
该语句会对 users 表中的每一条记录执行截取操作,返回 username 字段的前三个字符。
二、LEFT函数提取字段前几位
假设存在一个商品表:
SQLCREATE TABLE product ( id INT PRIMARY KEY, product_code VARCHAR(50), product_name VARCHAR(100) );
示例数据:
id product_code product_name 1 ABC202608001 商品A 2 XYZ202608002 商品B 3 DEF202608003 商品C
如果需要获取商品编码的前3位,可以执行:
SQLSELECT product_code, LEFT(product_code, 3) AS prefix FROM product;
查询结果:
product_code prefix ABC202608001 ABC XYZ202608002 XYZ DEF202608003 DEF
AS prefix 是给截取后的结果设置别名,实际项目中可以根据业务含义修改,例如 code_prefix、category_code 等。
三、WHERE条件中使用LEFT函数
LEFT() 不仅可以用于 SELECT 查询,也可以用于筛选数据。
例如,需要查询商品编码前三位为 ABC 的记录:
SQLSELECT * FROM product WHERE LEFT(product_code, 3) = 'ABC';
这种写法直观地表达了“判断字段前3位是否为 ABC”。
也可以直接使用字符串匹配:
SQLSELECT * FROM product WHERE product_code LIKE 'ABC%';
如果只是判断固定前缀,LIKE 'ABC%' 通常更适合索引优化;而 LEFT() 更适合已经需要对字符串进行截取、展示或进一步计算的场景。
四、LEFT函数处理中文字符串
LEFT() 截取的是字符数量,而不是简单按照字节数截取,因此处理中文时通常可以直接使用。
例如:
SQLSELECT LEFT('数据库技术', 3);
结果为:
数据库技
再例如:
SQLSELECT LEFT('MySQL数据库', 5);
结果为:
MySQL
如果需要截取中文内容:
SQLSELECT LEFT('数据库技术', 4);
结果为:
数据库技术
这里需要注意,MySQL 字符集配置会影响字符串的存储和处理方式。对于包含中文的数据库,建议使用 utf8mb4 字符集,以避免部分 Unicode 字符无法正常存储的问题。
五、LEFT函数与LENGTH函数的区别
实际使用 MySQL 字符串函数时,一个容易混淆的问题是“字符长度”和“字节长度”。
LEFT() 的第二个参数表示要返回的字符数量,而 LENGTH() 返回的是字符串占用的字节数。
例如:
SQLSELECT LENGTH('MySQL');
结果为:
5
对于中文:
SQLSELECT LENGTH('数据库');
如果数据库使用 UTF-8 字符集,结果通常不是2,而是对应字符占用的字节数。
而:
SQLSELECT CHAR_LENGTH('数据库');
返回的是:
3
因此,进行字符串截取时不要简单地将 LENGTH() 的结果理解为字符数量。
常见函数可以这样区分:
| 函数 | 主要作用 |
|---|---|
LEFT() | 从左侧截取指定数量字符 |
RIGHT() | 从右侧截取指定数量字符 |
SUBSTRING() | 从指定位置截取字符串 |
LENGTH() | 获取字符串字节长度 |
CHAR_LENGTH() | 获取字符串字符长度 |
六、LEFT函数处理NULL值
如果被截取的字段可能为 NULL,需要特别注意。
例如:
SQLSELECT LEFT(NULL, 3);
返回结果仍然是:
NULL
因此,如果业务要求空值统一显示为空字符串,可以结合 COALESCE():
SQLSELECT LEFT(COALESCE(product_code, ''), 3) AS prefix FROM product;
这样即使 product_code 为 NULL,最终也不会得到 NULL。
不过是否应该将 NULL 转换为空字符串,需要根据业务逻辑决定。NULL 和空字符串在数据库中代表的含义并不完全相同,不建议为了方便显示而在所有场景中统一替换。
七、LEFT函数长度超过字符串本身
如果指定的截取长度大于原字符串长度,MySQL 不会报错,而是直接返回整个字符串。
例如:
SQLSELECT LEFT('ABC', 10);
结果仍然是:
ABC
因此,通常不需要在调用 LEFT() 之前额外判断字符串长度。
例如:
SQLSELECT LEFT(product_code, 20) FROM product;
即使某些商品编码只有10个字符,也能够正常执行。
八、LEFT函数长度为0的情况
当第二个参数为0时,不会返回任何字符:
SQLSELECT LEFT('ABCDEF', 0);
结果为空字符串。
因此,如果截取长度来自程序变量或者数据库字段,需要确保长度符合业务预期。
例如:
SQLSELECT LEFT(product_code, 5) FROM product;
适合明确提取固定5位前缀的业务。
九、使用LEFT函数生成业务字段
LEFT函数在数据查询和报表处理中非常常见。例如订单编号:
SH202608290001 BJ202608290002 SH202608290003
其中前两位代表地区,可以使用:
SQLSELECT order_no, LEFT(order_no, 2) AS region_code FROM orders;
得到:
order_no region_code SH202608290001 SH BJ202608290002 BJ SH202608290003 SH
如果进一步结合 CASE,还可以转换成更直观的业务名称:
SQLSELECT order_no, CASE LEFT(order_no, 2) WHEN 'SH' THEN '上海' WHEN 'BJ' THEN '北京' ELSE '其他' END AS region_name FROM orders;
这种方式适合数据报表、统计查询等场景。
十、LEFT函数与SUBSTRING函数对比
提取字段前几位时,LEFT() 和 SUBSTRING() 都能够实现。
例如:
SQLSELECT LEFT(product_code, 3) FROM product;
使用 SUBSTRING() 可以写成:
SQLSELECT SUBSTRING(product_code, 1, 3) FROM product;
两者结果相同。
不过,如果需求明确是“从左侧提取前N个字符”,LEFT() 表达得更加简洁:
SQLLEFT(product_code, 3)
而 SUBSTRING() 更适合处理需要指定起始位置的复杂截取需求:
SQLSUBSTRING(product_code, 4, 6)
因此,可以根据实际需求选择函数。
十一、LEFT函数实现字段前N位提取的常见场景
实际开发中,LEFT() 的使用范围比较广。
1. 提取编号前缀
SQLSELECT LEFT(order_no, 2) AS order_prefix FROM orders;
适用于订单号、产品编码、设备编号等。
2. 提取手机号前3位
SQLSELECT LEFT(phone, 3) AS mobile_prefix FROM user_info;
可以用于简单的数据分类或统计。
3. 截取文本摘要
SQLSELECT LEFT(description, 50) AS summary FROM article;
可以快速生成固定长度的文本摘要。
需要注意的是,简单截取并不一定适合作为正式的文章摘要。如果文本包含中英文混排、特殊符号等内容,正式的摘要生成通常需要在应用层进行更完善的处理。
4. 提取日期字符串前几位
如果日期以字符串形式保存,例如:
2026-08-29
可以使用:
SQLSELECT LEFT(date_text, 4) FROM data_table;
获取年份:
2026
不过,如果字段本身是 DATE 类型,不建议为了截取日期而转换成字符串。对于日期字段,应优先使用 YEAR()、MONTH()、DAY() 等日期函数。
十二、LEFT函数使用时的性能注意事项
LEFT() 用于查询结果展示时通常没有明显问题,例如:
SQLSELECT LEFT(product_code, 3) FROM product;
但如果在大数据量表的 WHERE 条件中频繁使用:
SQLWHERE LEFT(product_code, 3) = 'ABC'
就需要关注执行计划和索引使用情况。
如果目标只是查询某个固定前缀,可以考虑:
SQLWHERE product_code LIKE 'ABC%'
在合适的索引和查询条件下,这种写法通常更有利于利用普通索引。
如果业务确实需要按照字符串前缀进行高频筛选,还可以根据具体场景考虑生成列、函数索引等方案。例如支持函数索引的 MySQL 版本可以针对表达式建立相应索引,具体方案需要结合数据量、查询频率和执行计划进行判断。
不要单纯为了“使用函数”而增加索引,实际优化应该以 EXPLAIN 等执行计划分析结果为依据。
十三、LEFT函数常见错误
错误一:参数顺序写反
正确写法:
SQLLEFT(product_code, 3)
不要写成:
SQLLEFT(3, product_code)
因为 LEFT() 的第一个参数必须是待截取的字符串,第二个参数才是截取长度。
错误二:把第二个参数当成结束位置
例如:
SQLLEFT(product_code, 5)
表示“从左边开始取5个字符”,并不是“截取到第5个位置之前”。
错误三:混淆字符和字节
对于中文、日文等多字节字符,不能简单根据 LENGTH() 判断应该截取多少个字符。
如果目标是按照字符数量处理字符串,应直接关注 LEFT() 的字符语义,以及 CHAR_LENGTH() 与 LENGTH() 的区别。
错误四:忽略NULL
如果字段允许为空:
SQLSELECT LEFT(product_code, 3) FROM product;
对应的 NULL 值结果仍然是 NULL。如果业务要求特殊处理,应显式使用 COALESCE() 或其他空值处理逻辑。
十四、实际开发中的推荐写法
如果只是提取字段前几位,推荐保持SQL简单清晰:
SQLSELECT product_code, LEFT(product_code, 3) AS product_prefix FROM product;
如果需要进行条件筛选:
SQLSELECT * FROM product WHERE product_code LIKE 'ABC%';
如果需要同时截取并处理空值:
SQLSELECT LEFT(COALESCE(product_code, ''), 3) AS product_prefix FROM product;
如果需要从字符串中间某个位置开始截取,则可以改用:
SQLSELECT SUBSTRING(product_code, 4, 5) FROM product;
这样能够让不同字符串处理函数各司其职,SQL也更容易维护。
总体来看,MySQL LEFT() 函数非常适合处理“字段前几位提取”这一类明确的字符串操作。它语法简单,代码可读性高,既可以用于 SELECT 展示,也可以参与条件判断、字段转换和数据统计。实际开发时,需要重点关注 NULL、中文字符、字符长度与字节长度的区别,以及在 WHERE 条件中使用函数可能带来的索引和性能问题。