mysql截取前n位可用left(str,n)或substring(str,1,n),索引从1开始;substring(str,0,n)返回空字符串;null值均返回null;多字节字符按字符计数。

MySQL 用 SUBSTRING() 或 LEFT() 截取前 N 位
MySQL 提供两个常用函数:如果只要前几位,LEFT(str, n) 更直观;SUBSTRING(str, 1, n) 效果相同,但参数顺序更通用(支持从任意位置截)。注意索引从 1 开始,不是 0。
常见错误是写成 SUBSTRING(str, 0, n) —— 这在 MySQL 中不会报错,但会返回空字符串,因为起始位置 0 被解释为“从开头前一位”,实际无效。
-
SELECT LEFT(name, 3) FROM users;→ 取 name 字段前 3 个字符 -
SELECT SUBSTRING(title, 1, 5) FROM posts;→ 等效,但更适合后续扩展为从第 2 位开始截 - 字段为
NULL时,两个函数都返回NULL,不报错也不转空字符串
PostgreSQL 必须用 SUBSTRING(),语法略有不同
PostgreSQL 不支持 LEFT(),必须用 SUBSTRING(),且标准语法是 SUBSTRING(str FROM start FOR length)。省略 FOR 部分会从起始位置取到末尾,容易误用。
典型陷阱是照搬 MySQL 写法:SUBSTRING(name, 1, 3) 在 PostgreSQL 中会报错,提示“function substring(unknown, integer, integer) does not exist”。
- 正确写法:
SELECT SUBSTRING(name FROM 1 FOR 3) FROM users; - 也可以用位置函数简写:
SUBSTRING(name, 1, 3)是 PostgreSQL 的非标准兼容写法,但依赖配置,不建议依赖 - 如果字段含多字节字符(如中文),
SUBSTRING按字符计数,不是字节,这点和 MySQL 一致
SQL Server 用 LEFT() 最稳妥,SUBSTRING() 参数顺序易混淆
SQL Server 支持 LEFT(str, n) 和 SUBSTRING(str, start, length),但要注意 start 是从 1 开始,且当 start 超出长度时返回空字符串,不是报错。
一个隐蔽问题是:如果字段是 TEXT 类型(旧版),LEFT() 可能截断不准确,应先转为 VARCHAR(MAX);现代推荐统一用 VARCHAR 或 NVARCHAR。
-
SELECT LEFT(description, 10) FROM products;→ 安全、清晰 -
SUBSTRING(description, 0, 10)是错的:起始位置 0 会被当作 1,但语义混乱,别这么写 - 对 Unicode 字段(
NVARCHAR),LEFT()正常按字符处理,无需额外转换
跨数据库可移植写法几乎不存在,别硬套一个函数
想写一条 SQL 在 MySQL、PostgreSQL、SQL Server 全部跑通?基本做不到。LEFT() 在 PostgreSQL 里不存在,SUBSTRING(... FROM ... FOR ...) 在 SQL Server 里不被识别,MySQL 虽然接受多种变体但行为细节有差异。
真正要兼顾多库时,要么用 ORM 层抽象(如 SQLAlchemy 的 func.left()),要么在应用层做判断。直接拼 SQL 时,最轻量的妥协是统一用 SUBSTRING(str, 1, n) —— 它在 MySQL 和 SQL Server 中有效,在 PostgreSQL 中需改写,不能一劳永逸。
别低估字符集影响:UTF-8 下一个中文字符占 3 字节,但所有主流数据库的字符串函数都按字符计数,不是字节。唯一例外是某些老版本 MySQL 的 utf8 编码(非 utf8mb4),可能无法正确处理 emoji,但这属于编码配置问题,不是截取函数本身的锅。










