SQL字符串处理核心是理解“数据不可变”和“每步生成新值”,关键在正确应对NULL、记清索引从1开始、注意字符边界,再依场景选函数。

SQL字符串处理的核心不在记住函数名,而在理解“数据不可变”和“每步生成新值”这两个底层逻辑。所有字符串操作都是基于原始字段做计算,不修改原数据,也不支持链式调用(除少数数据库如PostgreSQL支持||拼接外),写错顺序或忽略空值就容易出结果偏差。
一、拼接:别只盯CONCAT,NULL才是真坑
CONCAT函数多数数据库都支持,但它对NULL的处理很“严格”——只要任一参数为NULL,整个结果就是NULL。比如:SELECT CONCAT(first_name, ' ', last_name) FROM users;
若first_name为NULL,结果直接是NULL,不是你期待的“空格+姓”。
- MySQL可用
CONCAT_WS(' ', first_name, last_name),自动跳过NULL,用空格连接非空项 - 通用写法是用COALESCE兜底:
CONCAT(COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) - PostgreSQL推荐用
||操作符,配合NULLIF或COALESCE更灵活
二、截取与定位:SUBSTR/SUBSTRING不是万能,起始位置规则要记清
SUBSTR(MySQL/Oracle)和SUBSTRING(SQL Server/PostgreSQL)本质一样,但起始位置从1开始(不是0!)。常犯错误是把索引当编程语言习惯来用。
-
SUBSTR('hello', 2, 3)→ 'ell'(从第2位起取3个字符) - 想取后3位?别硬算长度,用负数偏移(MySQL/PostgreSQL支持):
SUBSTR('hello', -3)→ 'llo' - 定位字符位置用
INSTR(MySQL)或CHARINDEX(SQL Server)或POSITION(PostgreSQL),返回从1开始的序号,没找到返回0或NULL,需判断
三、替换与清洗:REPLACE只做字面替换,正则才是进阶关键
REPLACE只能做简单全量替换,无法处理“去掉所有数字”或“提取邮箱”这类需求。真正清洗靠正则函数,但各库差异大:
- MySQL 8.0+ 支持
REGEXP_REPLACE,如:REGEXP_REPLACE(phone, '[^0-9]', '')提纯数字 - PostgreSQL用
REGEXP_REPLACE(text, pattern, replace),支持分组引用,如REGEXP_REPLACE(email, '^(.+)@(.+)$', '\2')提取域名 - SQL Server 2017+ 可用
STRING_SPLIT配合FOR XML模拟正则,但更推荐升级到2022用TRANSLATE或CLR集成
四、大小写与空格:TRIM不只是去空格,方向和字符集要注意
TRIM默认只去首尾空格(ASCII 32),遇到全角空格、制表符、换行符会失效。大小写转换也受数据库字符集和排序规则(COLLATION)影响。
- 安全去空白:
TRIM(BOTH FROM TRIM(LEADING '\t\n\r ' FROM TRIM(TRAILING '\t\n\r ' FROM col)))(多层嵌套保底) - MySQL可指定字符:
TRIM(LEADING '.' FROM '...hello...')→ 'hello...' - UPPER/LOWER在中文或带重音字符(如é)上可能异常,建议业务层处理或确认数据库COLLATION是否支持Unicode(如utf8mb4_unicode_ci)
基本上就这些。字符串处理看着零碎,其实就三条线:怎么拼、怎么切、怎么换。把NULL、索引起点、字符边界这三道坎跨过去,再结合业务场景选对函数,就能稳住大部分需求。










