reverse函数在mysql和sql server中可直接反转字符串,但仅逐字节机械翻转、不识别字符边界,对unicode可能出错,且postgresql等数据库不支持。

REVERSE函数在MySQL和SQL Server中能直接反转字符串
REVERSE() 是 MySQL 和 SQL Server 原生支持的字符串函数,作用就是把输入字符串逐字符倒序排列。它不修改原数据,只返回新字符串,所以常用于 SELECT 或 WHERE 子句中做临时处理。
常见错误是以为它能“原地修改字段”或“自动识别后缀边界”,其实它只是机械翻转——'hello.txt' 经 REVERSE() 变成 'txth.olleh',不是 'txt.hello'。想提取后缀,得配合 LEFT()、LOCATE()(MySQL)或 CHARINDEX()(SQL Server)一起用。
- MySQL 示例:提取文件扩展名(假设扩展名最多4字符):
SELECT REVERSE(LEFT(REVERSE(filename), 4)) FROM files;
- SQL Server 示例:同理,但用
CHARINDEX定位点更稳妥:SELECT RIGHT(filename, CHARINDEX('.', REVERSE(filename)) - 1) FROM files; - PostgreSQL 不支持
REVERSE(),得用string_to_array()+array_reverse()或substring()拼接,效率低得多
用REVERSE配合SUBSTRING/RIGHT提取后缀时必须先翻转再定位
直接 SUBSTRING(filename, LEN(filename) - 2, 3) 这类写法靠猜长度,不可靠。正确思路是:先翻转整个字符串,找第一个 '.' 出现的位置,再取其前若干字符,最后再翻回来(或用 RIGHT 避免二次翻转)。
MySQL 中典型安全写法:
SELECT SUBSTRING_INDEX(filename, '.', -1) AS ext FROM files;——但这不是用
REVERSE,而是内置函数。如果非要走 REVERSE 路线,必须注意:-
REVERSE()对 NULL 返回 NULL,字段为空时结果不可预期 - 多点文件名如
'archive.tar.gz',REVERSE()+LEFT(..., 3)会错取'zg.',应优先用SUBSTRING_INDEX(filename, '.', -1)(MySQL)或PARSENAME()(SQL Server,仅限4段以内) - 区分大小写:
REVERSE('TXT')→'TXT',反转后大小写不变,别误以为能统一后缀格式
性能影响小,但嵌套过深会拖慢查询
REVERSE() 本身是 O(n) 时间复杂度,对单字段短字符串几乎无感;但若在 WHERE 条件里对列用 REVERSE(col),会导致该列索引失效——因为数据库无法用索引快速匹配翻转后的值。
- 避免:
WHERE REVERSE(filename) LIKE 'tx%' —— 全表扫描
- 可接受:
WHERE filename LIKE '%.txt' —— 能用后缀索引(MySQL 8.0+ 支持函数索引,但需显式创建)
- 如果真要查反转模式,建议提前计算并存入冗余字段,加索引
跨数据库兼容性差,别默认它存在
SQLite、PostgreSQL、Oracle 都没有 REVERSE() 函数。Oracle 有 UTL_RAW.REVERSE() 但只适用于 RAW 类型;PostgreSQL 需写 array_to_string(array_reverse(string_to_array(str, '')), ''),又长又慢。
真正需要跨库的场景,要么用应用层反转(Python 的 s[::-1]),要么封装成视图或存储过程屏蔽差异。硬在 SQL 里强推 REVERSE() 会导致迁移成本陡增。
最常被忽略的一点:即使在同一数据库里,REVERSE() 对 Unicode 多字节字符(如中文、emoji)也按字节翻转,不是按字符——REVERSE('??') 可能崩出乱码,因为这个 emoji 实际占 4 字节以上。真要处理 Unicode,别信 REVERSE()。











