SQL字符串函数

一、字符串拼接与组合

基础拼接

  • CONCAT(str1, str2, ...):连接多个字符串,任意参数为NULL则结果为NULL

    sql 复制代码
    SELECT CONCAT('Hello', ' ', 'World') -- 'Hello World'
  • CONCAT_WS(separator, str1, str2, ...):带分隔符拼接,自动跳过NULL值

    sql 复制代码
    SELECT CONCAT_WS('-', '2025', '12', '09') -- '2025-12-09'

数据库特有方式

  • MySQL/PostgreSQL:支持||运算符(PostgreSQL推荐)
  • SQL Server:支持+运算符(注意类型转换问题)
  • Oracle:优先使用||运算符

多行聚合拼接

数据库 函数 特点
MySQL GROUP_CONCAT([DISTINCT] expr [ORDER BY] [SEPARATOR]) 支持去重和排序,默认长度限制1024
PostgreSQL string_agg(expr, separator [ORDER BY]) 排序语法更简洁
SQL Server STRING_AGG(expr, separator) [WITHIN GROUP (ORDER BY)] 2017+支持,2022+才支持排序
Oracle LISTAGG(expr, separator) WITHIN GROUP (ORDER BY) 必须指定排序,有长度限制
sql 复制代码
GROUP_CONCAT(
  [DISTINCT] 字段名          -- 去重
  [ORDER BY 排序字段 [ASC|DESC]]  -- 排序
  [SEPARATOR '分隔符']       -- 自定义分隔符
)

SELECT 
  country,
  GROUP_CONCAT(DISTINCT city) AS unique_cities  -- 自动去重
FROM locations
GROUP BY country;

SELECT 
  dept_id,
  GROUP_CONCAT(
    employee_name 
    ORDER BY hire_date DESC  -- 按入职时间降序
    SEPARATOR ' | '         -- 竖线分隔
  ) AS seniority_list
FROM employees
GROUP BY dept_id;


SELECT 
  project_id,
  GROUP_CONCAT(
    CONCAT(name, '(', emp_id, ')')  -- 组合字段
    SEPARATOR '; '                  -- 分号分隔
  ) AS project_team
FROM project_members
GROUP BY project_id;

二、字符串截取与提取

基础截取

  • SUBSTRING(str, start, length) / SUBSTR():从指定位置提取子串

    sql 复制代码
    SELECT SUBSTRING('Database', 4, 4) -- 'abas'(从第4位取4个字符)
  • LEFT(str, length) / RIGHT(str, length):从左侧/右侧提取

    sql 复制代码
    SELECT LEFT('Example', 3), RIGHT('Example', 4) -- 'Exa', 'mple'

高级用法

  • 动态截取:结合定位函数提取分隔符后的内容

    sql 复制代码
    -- 提取@后的域名
    SELECT SUBSTRING(email, POSITION('@' IN email)+1) 
    FROM users
    
    函数分解:
    POSITION('@' IN email):查找@符号在email字段中的位置索引(从1开始计数)
    SUBSTRING(email, position_value + 1):从@符号后一位开始截取子字符串
    示例:
    若邮箱为user@example.com,结果为example.com
    若邮箱为admin@company.co.uk,结果为company.co.uk
  • 反向截取:MySQL支持负数起始位置(从尾部计数)

    sql 复制代码
    SELECT SUBSTRING('HelloWorld', -5) -- 'World'(倒数第5位开始)

三、字符串查找与定位

  • LOCATE(substr, str [, start])(MySQL):返回子串首次出现位置

  • INSTR(str, substr)(Oracle/PostgreSQL):同上,参数顺序相反

    sql 复制代码
    SELECT LOCATE('world', 'Hello world'), INSTR('Hello world', 'world')
    -- 均返回7(位置从1开始计数)
  • POSITION(substr IN str):SQL标准语法,功能类似

  • CHARINDEX(substr, str)(SQL Server):功能相同

四、字符串替换

基础替换

  • REPLACE(str, old_sub, new_sub):全局替换指定子串

    sql 复制代码
    SELECT REPLACE('Hello world', 'world', 'SQL') -- 'Hello SQL'

正则替换(高级场景)

数据库 函数 示例
MySQL REGEXP_REPLACE(str, pattern, replace) REGEXP_REPLACE('a1b2c3', '[0-9]', '') → 'abc'
PostgreSQL REGEXP_REPLACE(str, pattern, replace) 支持更丰富的正则语法
Oracle REGEXP_REPLACE(str, pattern, replace [, flags]) 可通过flags控制匹配模式

五、大小写转换与格式化

  • UPPER(str) / LOWER(str):大小写转换

    sql 复制代码
    SELECT UPPER('sql'), LOWER('SQL') -- 'SQL', 'sql'
  • INITCAP(str)(PostgreSQL/Oracle):首字母大写

    sql 复制代码
    SELECT INITCAP('hello world') -- 'Hello World'

六、长度计算与修剪

长度计算(注意字符集影响)

  • LENGTH(str):返回字节长度(受字符集影响)

  • CHAR_LENGTH(str):返回字符个数(与字符集无关)

    sql 复制代码
    -- UTF-8环境下
    SELECT LENGTH('你好'), CHAR_LENGTH('你好') -- 6(3字节/汉字), 2

修剪函数

  • TRIM([BOTH|LEADING|TRAILING] [remstr FROM] str):去除指定字符

    sql 复制代码
    SELECT TRIM('  Hello  '), TRIM(LEADING 'x' FROM 'xxTest')
    -- 'Hello', 'Test'
  • LTRIM(str) / RTRIM(str):仅去除左侧/右侧空格

七、高级字符串操作

填充函数

  • LPAD(str, len, padstr) / RPAD(str, len, padstr):左右填充

    sql 复制代码
    SELECT LPAD('123', 5, '0'), RPAD('123', 5, '0') -- '00123', '12300'

翻译函数

  • TRANSLATE(str, from_str, to_str):字符级替换

    sql 复制代码
    SELECT TRANSLATE('123-456', '14', 'AX') -- 'A23-X56'(1→A,4→X)

正则匹配

数据库 操作符/函数 示例
MySQL REGEXP / RLIKE WHERE name REGEXP '^[A-Z]'
PostgreSQL ~(区分大小写)/ ~*(不区分) WHERE name ~* '^[a-z]'
Oracle REGEXP_LIKE(str, pattern) WHERE REGEXP_LIKE(name, '^[A-Z]')
SQL Server PATINDEX('%pattern%', str) 功能有限,需用%通配符

八、数据库差异速查表

九、性能与最佳实践

  1. 索引使用:避免在WHERE子句中对索引列使用函数

    sql 复制代码
    -- 低效:无法使用索引
    WHERE LOWER(username) = 'admin'
    
    -- 高效:提前标准化存储
    WHERE username = 'admin' -- 存储时已转小写
  2. NULL处理:优先使用CONCAT_WS处理可能为NULL的字段拼接

  3. 长度限制:使用GROUP_CONCAT时注意默认长度限制(MySQL)

    复制代码
    SET SESSION group_concat_max_len = 1000000; -- 临时调整
  4. 字符集注意:处理多字节字符时,始终用CHAR_LENGTH判断字符数

相关推荐
剩下了什么5 小时前
MySQL JSON_SET() 函数
数据库·mysql·json
山峰哥6 小时前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
较劲男子汉6 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
java搬砖工-苤-初心不变6 小时前
MySQL 主从复制配置完全指南:从原理到实践
数据库·mysql
山岚的运维笔记8 小时前
SQL Server笔记 -- 第18章:Views
数据库·笔记·sql·microsoft·sqlserver
roman_日积跬步-终至千里9 小时前
【LangGraph4j】LangGraph4j 核心概念与图编排原理
java·服务器·数据库
汇智信科9 小时前
打破信息孤岛,重构企业效率:汇智信科企业信息系统一体化运营平台
数据库·重构
野犬寒鸦9 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
WHD3069 小时前
苏州数据库(SQL Oracle)文件损坏修复
hadoop·sql·sqlite·flume·memcached
晚霞的不甘10 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d