left和right函数用于从字符串左/右端截取指定非负整数长度的字符,参数为string_expression和length;length为负或null时多数数据库报错,超长则返回原字符串,postgresql默认不支持需用substring替代。

LEFT 和 RIGHT 函数的基本用法与参数含义
LEFT 和 RIGHT 是 SQL 中用于截取字符串开头或结尾固定长度子串的标量函数,几乎所有主流数据库(SQL Server、MySQL 8.0+、PostgreSQL 通过 LEFT/RIGHT 扩展、SQLite)都支持,但行为细节有差异。核心参数只有两个:string_expression 和 length,后者必须是非负整数。
常见错误是传入负数或 NULL 给 length —— 多数数据库会直接报错(如 SQL Server 报 Invalid length parameter passed to the LEFT or SUBSTRING function),MySQL 则返回空字符串,容易掩盖逻辑问题。
-
LEFT('hello world', 5)→'hello' -
RIGHT('hello world', 6)→'world '(注意末尾空格) - 若
length超过原字符串长度(如LEFT('abc', 10)),多数引擎返回原字符串,不报错
不同数据库对 LEFT/RIGHT 的兼容性差异
MySQL 在 8.0 之前不原生支持 LEFT/RIGHT,需用 SUBSTRING(str, 1, n) 或 SUBSTR(str, -n) 模拟;PostgreSQL 默认不提供这两个函数,需安装 pg_trgm 扩展或用 SUBSTRING(str FROM 1 FOR n) / SUBSTRING(str FROM LENGTH(str)-n+1) 替代。
SQL Server 和 Azure SQL 完全支持,且性能较好;SQLite 自 3.29.0 起支持,但旧版本只能靠 SUBSTR。
- MySQL 5.7:用
SUBSTRING(col, 1, 3)代替LEFT(col, 3) - PostgreSQL:写成
SUBSTRING(col FROM 1 FOR 4)更稳妥 - SQL Server:可放心用
LEFT(col, 2),但注意col为TEXT类型时需先转VARCHAR
处理 NULL 和空字符串时的隐式行为
LEFT 和 RIGHT 对 NULL 输入一律返回 NULL,不会抛异常,但容易在后续比较或连接中引发意外结果(比如 WHERE LEFT(name, 2) = 'Li' 会自动过滤掉所有 name 为 NULL 的行)。空字符串 '' 传入后,无论 length 多大,结果都是 ''。
- 安全写法:显式判断
WHERE name IS NOT NULL AND LEFT(name, 2) = 'Li' - 避免链式调用:不要写
LEFT(RIGHT(col, 10), 3),先RIGHT再LEFT可能因中间结果为空而失效 - 长度动态计算时慎用:如
LEFT(email, CHARINDEX('@', email) - 1),若 email 不含@,CHARINDEX返回 0,导致LEFT第二参数为 -1,SQL Server 直接报错
替代方案:SUBSTRING 更通用但更易出错
当需要从中间截取、或起始位置不确定时,SUBSTRING(或 SUBSTR)是唯一选择,但它要求你精确控制起始偏移和长度,稍有不慎就越界或漏字符。例如提取域名部分:SUBSTRING(email, CHARINDEX('@', email) + 1, LEN(email)) 中第二个参数若为 0 或负数,结果不可控。
-
SUBSTRING('a@b.com', 3, 100)→'b.com'(超出长度自动截断) -
SUBSTRING('abc', 5, 2)→ 返回空字符串(不是错误),这点和LEFT行为一致 - 建议:固定头尾截取优先用
LEFT/RIGHT,其余场景再上SUBSTRING,降低认知负担
实际使用时,最常被忽略的是字段类型隐式转换——比如对 INT 字段直接套 LEFT(id, 2),某些数据库会静默转成字符串再截,有些则报类型错误。务必确认源字段是否已是字符串类型,否则加一层 CAST(id AS VARCHAR) 更稳。











