postgresql 14+ 默认支持 left 和 right 函数,但需验证是否启用;13 及更早版本不支持,须用 substring 替代;null 返回 null,超长返回原串,空格和字符长度差异易致截取偏差。

PostgreSQL 14+ 默认支持 LEFT 和 RIGHT 函数,但行为和兼容性比你想象中更敏感——尤其在字段含空值、长度不足或跨版本迁移时,容易返回意外结果。
LEFT/RIGHT 在 PostgreSQL 中是否可用?看版本和配置
PostgreSQL 14 之前(如 13 或更早)压根没有内置 LEFT 和 RIGHT,直接执行会报错:ERROR: function left(unknown, integer) does not exist。即使升级到 14+,也得确认函数已加载(默认启用,但某些精简部署或自定义 pg_catalog 可能禁用)。
实操建议:
- 先运行
SELECT LEFT('test', 2);验证是否支持;不支持就立刻切到SUBSTRING - 生产环境若需跨版本兼容,统一用
SUBSTRING(col FROM 1 FOR n)和SUBSTRING(col FROM LENGTH(col) - n + 1 FOR n) - 别依赖
pg_trgm扩展来“补”这两个函数——它不提供LEFT/RIGHT,那是常见误解
LEFT(col, n) 返回空、NULL 或全长?取决于这三件事
LEFT 对 n 的处理看似简单,但实际输出受字段值类型、长度、是否为 NULL 共同影响:
- 当
col是NULL→ 整个LEFT结果为NULL(不会报错,但可能被 WHERE 过滤掉) - 当
col是空字符串''→LEFT('', 5)返回''(不是NULL,也不是 5 个空格) - 当
n > LENGTH(col)→ 安全返回原字符串,不截断也不报错;但如果你依赖“固定长度输出”,这就成了隐患
例如提取订单号前 6 位:LEFT(order_no, 6),若某行 order_no = 'AB12',结果就是 'AB12',而非补空或报错——这点常被日志分析或下游系统误判为“数据异常”。
RIGHT 截取末尾时,空格和字节长度是隐形陷阱
RIGHT 表面只管“从右数 n 个字符”,但 PostgreSQL 中的 CHARACTER vs BYTE 概念会让结果出人意料:
-
LENGTH()返回字符数(Unicode 安全),而OCTET_LENGTH()返回字节数;RIGHT按字符计数,所以中文、emoji 不会“被截半” - 但若字段类型是
CHAR(n)(定长),末尾填充空格会被RIGHT真实计入——RIGHT('abc ', 3)返回'c '(含两个空格) - 想剔除尾部空格再截?得组合
RTRIM():RIGHT(RTRIM(col), 4)
典型场景:提取手机号后 4 位。如果原始字段是 CHAR(11) 类型且存了 '13812345678',RIGHT(col, 4) 实际拿到的是 '5678';但如果该字段被错误地用空格补齐到 11 位,结果可能是 '678 '(带空格)。
替代方案:SUBSTRING 更可控,也更可移植
当你要确保逻辑稳定、避免版本或 NULL 问题,SUBSTRING 是更底层、更明确的选择:
-
LEFT(col, 3)等价于SUBSTRING(col FROM 1 FOR 3),但后者在所有 PG 版本都可用 -
RIGHT(col, 4)等价于SUBSTRING(col FROM LENGTH(col) - 3 FOR 4)(注意:LENGTH(col) - n + 1是起始位置) - 遇到 NULL 字段要兜底?
SUBSTRING(COALESCE(col, ''), FROM 1 FOR 3)比嵌套CASE WHEN更简洁
真正麻烦的从来不是“怎么写”,而是“哪一行会悄悄打破你的长度假设”。检查真实数据分布永远比查文档快:SELECT col, LENGTH(col), LEFT(col, 5), RIGHT(col, 5) FROM t LIMIT 20; —— 这一行命令暴露的问题,往往比翻三天手册还准。










