LEFT和RIGHT函数在MySQL、SQL Server中直接支持,PostgreSQL需用substring()模拟,SQLite不原生支持;截取时需处理NULL、长度不足及类型转换问题,并配合LPAD等补位,且LEFT无法使用索引。

LEFT 和 RIGHT 函数在不同数据库里名字不一样
MySQL、PostgreSQL(需安装 pg_trgm 或用 substring)、SQL Server 都原生支持 LEFT() 和 RIGHT(),但 SQLite 和旧版 PostgreSQL 默认不提供——它们得靠 substr() 或 substring() 模拟。比如 PostgreSQL 里写 LEFT(col, 3) 会报错 function left(unknown, integer) does not exist,必须改用 substring(col, 1, 3) 或 left(col::text, 3)(如果列是 varchar 但隐式类型推导失败)。
截取固定位数编号时,NULL 和长度不足最常出问题
假设编号字段叫 order_id,你想取前 4 位做分类标签,直接写 LEFT(order_id, 4) 看似简单,但实际运行时容易踩三个坑:
-
order_id是NULL→ 整个结果变NULL,不是空字符串 -
order_id实际只有 2 位(如'A1')→LEFT('A1', 4)仍返回'A1',不会补空格或报错,但业务上可能期望统一 4 位(比如补零或抛异常) -
order_id是数字类型(如INT)→ MySQL 会自动转字符串,但 SQL Server 可能报错“无法将数据类型 int 转换为 varchar”,得显式用CAST(order_id AS VARCHAR)
想保证截出来都是 4 位?得组合使用 LPAD 或 REPLICATE
单纯 LEFT 不负责补位,要“不够就补零”得加一层处理。MySQL 可用 LPAD(LEFT(order_id, 4), 4, '0');SQL Server 得写成 RIGHT('0000' + LEFT(CAST(order_id AS VARCHAR), 4), 4);PostgreSQL 则推荐 lpad(left(col::text, 4), 4, '0')。注意顺序:先 LEFT 再 LPAD,别反过来,否则可能截掉补的零。
性能上,LEFT/RIGHT 本身几乎无开销,但索引会失效
LEFT(order_id, 4) = 'ABCD' 这种条件无法走 order_id 字段的 B-tree 索引——因为函数改变了原始值。真要高频按前缀查,应该另建计算列并索引(如 MySQL 的 GENERATED COLUMN + INDEX),或者用前缀索引(INDEX(order_id(4)))。另外,如果编号含空格或不可见字符(比如从 Excel 导入的 ' A123 '),LEFT 会把开头空格也算进去,得先 TRIM()。

















