在SQL数据处理过程中,模糊搜索和去重是两类非常常见的需求,但当两者需要结合使用时,常规的去重手段往往无法直接生效。比如我们有一批用户备注数据,备注中包含不同格式的手机号、邮箱等标识信息,需要按照标识信息做模糊搜索,同时把标识信息不同但核心内容相同的记录去重,这时候就可以借助REGEXP_REPLACE正则函数来实现。

REGEXP_REPLACE函数基础介绍
REGEXP_REPLACE是SQL中用于正则替换的内置函数,核心作用是根据指定的正则表达式规则,匹配字符串中的目标内容,再将其替换为指定的新内容。不同数据库的函数参数略有差异,但核心逻辑一致,基本语法如下:
-- MySQL中REGEXP_REPLACE语法 REGEXP_REPLACE(source_string, pattern, replacement) -- source_string:待处理的原始字符串 -- pattern:正则表达式匹配规则 -- replacement:替换后的新字符串
模糊搜索去重的实现思路
要实现模糊搜索后去重,整体思路可以分为三步:
- 第一步:使用LIKE或者REGEXP完成模糊搜索,筛选出符合初步条件的记录
- 第二步:使用REGEXP_REPLACE对模糊搜索结果中的可变部分(比如不同格式的标识、多余的空格符号等)进行统一替换,得到标准化的对比字段
- 第三步:对标准化后的对比字段使用DISTINCT或者GROUP BY完成去重
具体实现示例
场景说明
假设我们有一张用户反馈表user_feedback,表结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 反馈ID |
| content | varchar | 反馈内容 |
反馈内容中包含用户的手机号,格式可能是13812345678、138-1234-5678、138 1234 5678三种,现在需要搜索所有包含手机号的反馈,同时把同一手机号的不同格式反馈去重,只保留一条。
MySQL实现代码
-- 先模糊搜索包含手机号的记录,再统一手机号格式,最后去重
SELECT DISTINCT
REGEXP_REPLACE(
content,
-- 匹配所有手机号格式:连续11位数字,或者带横杠、空格的11位数字
'([0-9]{3}[- ]?)?[0-9]{4}[- ]?[0-9]{4}',
'STANDARD_PHONE' -- 把所有手机号替换为统一标识
) AS standard_content,
content
FROM user_feedback
WHERE content REGEXP '[0-9]{11}|[0-9]{3}[- ][0-9]{4}[- ][0-9]{4}'
GROUP BY standard_content;
Oracle实现代码
Oracle的REGEXP_REPLACE参数和MySQL略有不同,需要指定起始位置、匹配次数等参数,实现逻辑一致:
SELECT DISTINCT
REGEXP_REPLACE(
content,
'([0-9]{3}[- ]?)?[0-9]{4}[- ]?[0-9]{4}',
1,
0,
'STANDARD_PHONE'
) AS standard_content,
content
FROM user_feedback
WHERE REGEXP_LIKE(content, '[0-9]{11}|[0-9]{3}[- ][0-9]{4}[- ][0-9]{4}')
GROUP BY standard_content;
注意事项
使用REGEXP_REPLACE实现模糊搜索去重时需要注意以下几点:
- 正则表达式的匹配规则要尽可能覆盖所有需要统一的格式,避免遗漏导致去重不彻底
- 替换后的统一标识不要和原内容中的其他内容冲突,否则会导致误判
- 如果数据量较大,建议先对模糊搜索的条件建立合适的索引,提升查询效率
- 不同数据库的REGEXP_REPLACE函数参数和正则语法支持略有差异,需要根据实际使用的数据库调整代码
SQLREGEXP_REPLACE模糊搜索去重修改时间:2026-06-14 20:03:18