
SQL 字符串函数 CONCAT 和 SUBSTRING 是处理文本拼接与截取最常用、最直接的工具。用对了,能大幅减少冗余字段、避免应用层字符串操作,提升查询可读性与执行效率。
CONCAT:安全拼接,避开 NULL 坑
CONCAT 会自动跳过 NULL 值,比用 + 或 || 更健壮。例如:CONCAT('姓名:', name, ',年龄:', age) 即使 name 为 NULL,结果仍是 '姓名:,年龄:25'(注意空字段),不会整体变 NULL。
- MySQL 8.0+ 和 PostgreSQL 支持标准 CONCAT;SQL Server 从 2012 起支持;Oracle 用
CONCAT()但只接受两个参数,多字段建议改用||或LISTAGG - 若需统一空值显示(如把 NULL 变成 '未知'),搭配
COALESCE(name, '未知')使用更可控 - 避免在 WHERE 子句中对字段做 CONCAT 计算(如
WHERE CONCAT(first_name, last_name) = '张三'),会导致索引失效;应优先考虑生成列或提前计算好存储字段
SUBSTRING:精准定位,灵活切片
SUBSTRING(别名 SUBSTR)用于按位置提取子串,核心是起始位置和长度。不同数据库索引起点略有差异:MySQL/PostgreSQL/SQL Server 从 1 开始,Oracle 也从 1 开始(不是 0)。
- 基本写法:
SUBSTRING(phone, 1, 3)提取手机号前三位;SUBSTRING(email, INSTR(email, '@') + 1)(MySQL)或SUBSTRING(email, POSITION('@' IN email) + 1)(PostgreSQL)提取域名部分 - 长度参数可省略,表示“从起点截到末尾”,比如
SUBSTRING(path, LENGTH('/users/') + 1)快速剥离固定前缀 - 配合
CHAR_LENGTH和POSITION/INSTR实现动态截取,比硬编码位置更适应数据变化
组合使用:构造标准化输出
真实业务中常需先截取再拼接。例如生成脱敏邮箱:CONCAT(LEFT(email, 2), '***', SUBSTRING(email, LENGTH(email) - 3))(MySQL)得到 z***@xxx.com;或提取路径最后一级目录:SUBSTRING_INDEX(url, '/', -1)(MySQL)等价于 SUBSTRING(url, LENGTH(url) - LOCATE('/', REVERSE(url)) + 2)(通用写法)。
- 嵌套不宜过深,超过两层建议用 CTE 或派生表提升可维护性
- 字符串操作在大数据量下有性能开销,若该逻辑高频且稳定,考虑在写入时预计算并存入新字段
- 注意字符集影响:UTF8MB4 下一个中文占 1 个字符长度,SUBSTRING 按字符计数,不是字节
不复杂但容易忽略细节。掌握 CONCAT 的容错性和 SUBSTRING 的定位逻辑,就能稳住大多数文本加工需求。










