LEFT函数在MySQL、SQL Server、PostgreSQL(14+)和SQLite中语法为LEFT(str, n),Oracle及PostgreSQL 13-需用SUBSTR或SUBSTRING替代;参数不支持负数,NULL导致结果为NULL;截取超长时自动返回原串,但WHERE中滥用会引发全表扫描。

LEFT函数在不同数据库中的语法差异
MySQL、SQL Server、PostgreSQL(从14版起)和SQLite都支持LEFT(),但Oracle和旧版PostgreSQL不支持。如果执行SELECT LEFT('hello', 2)报错“function left does not exist”,大概率是你在用Oracle或PostgreSQL 13及更早版本。
替代方案:
• Oracle用SUBSTR('hello', 1, 2)
• PostgreSQL 13及以下用SUBSTRING('hello' FROM 1 FOR 2)或SUBSTR('hello', 1, 2)
• 所有数据库通用写法是SUBSTRING(col_name, 1, n),兼容性更高
LEFT函数的参数不能为负数或NULL
传入负长度会直接报错,比如LEFT('abc', -1)在SQL Server中提示“Invalid length parameter passed to the LEFT or SUBSTRING function”。MySQL虽不报错但返回空字符串,容易掩盖逻辑错误。
常见陷阱:
• 从另一列计算长度时未加COALESCE,如LEFT(name, char_length_limit),当char_length_limit为NULL时结果恒为NULL
• 动态截取前N位但N可能超出原字符串长度——LEFT对此安全,不会报错,自动返回全长,这点比SUBSTRING更宽容
用LEFT提取文件扩展名或邮箱用户名这类固定模式
比如从'report_v2.pdf'中取扩展名,不能只靠LEFT,得配合CHARINDEX或POSITION找最后一点位置。SQL Server示例:RIGHT(filename, CHARINDEX('.', REVERSE(filename)) - 1);MySQL可写成SUBSTRING_INDEX(filename, '.', -1)。
但如果目标明确是“取@之前的部分”,LEFT(email, LOCATE('@', email) - 1)就足够——注意LOCATE没找到时返回0,减1变-1,导致LEFT出错,所以必须加判断:LEFT(email, IF(LOCATE('@', email) > 0, LOCATE('@', email) - 1, LENGTH(email)))
性能影响:LEFT本身几乎无开销,但别在WHERE里滥用
LEFT(phone, 3) = '138'这种写法无法走索引(除非建函数索引),等价于全表扫描。比起用LEFT,更推荐用phone LIKE '138%',语义相同且能命中索引。
其他要注意的点:
• 字符集影响长度计算:UTF8MB4下中文算1个字符,但LEFT按字符数而非字节数截取,通常符合预期
• 如果字段含前导空格,LEFT会一并截取,必要时先TRIM()
• 在视图或CTE中频繁用LEFT生成新列,对查询计划无实质负担,但增加结果集宽度
实际业务里最容易被忽略的是跨数据库迁移时硬编码LEFT——看着简单,一换库就挂。宁可多写几行CASE WHEN或统一用SUBSTRING,也比后期排查兼容性问题省事。

















