浅谈oracle数据库相似度比较函数UTL_MATCH.edit_distance_similarity

博客介绍了数据库操作中,Oracle提供的utl_match.edit_distance_similarity函数用于相似度比较。分析了该函数运行结果的特点,如与对比对象顺序无关、相似度数值会四舍五入。还解释了对比对象完全不同但相似度不为0的原因,涉及匹配规则等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在数据库操作中,有时会用到相似度的比较,oracle为大家提供了一个很好用的函数:utl_match.edit_distance_similarity

比如:

SELECT UTL_MATCH.edit_distance_similarity('张三','李四') FROM dual;
SELECT UTL_MATCH.edit_distance_similarity('张三','张二麻子') FROM dual;
SELECT UTL_MATCH.edit_distance_similarity('张二麻子','张三') FROM dual;

运行结果:

0
34
34

从运行结果可以看出两个问题,1.结果与对比的两个对象的顺序无关;2.相似度的数值存在四舍五入的情况。

有时候在使用相似度函数时,对比的两个对象完全不同,但相似度的数值不为0。

比如:

SELECT UTL_MATCH.edit_distance_similarity('张二麻子111','李四') FROM dual;
SELECT UTL_MATCH.edit_distance_similarity('张二麻子22','李四') FROM dual;

运行结果:

7
8

出现以上情况,这是因为:两个参数中字符长的长度作为分母,汉字为2个长度单位,匹配的长度为分子,结果四舍五入; 匹配规则类似sql中的like'%a%','a%','%a'去匹配所有字符,例如UTL_MATCH.edit_distance_similarity('我1你','他1')=0/5=0,因为虽然都有1,但前者1在中间,相当于like %1%,而后者相当于like %1,二者不作相似。

如有其他见解的你,请不吝赐教

### Oracle 中实现相似度匹配的模糊搜索 在 Oracle 数据库中,传统的 `LIKE` 和正则表达式虽然能够满足基本的模糊查询需求,但在涉及更复杂的相似度匹配时显得力不从心。为了支持基于相似度的模糊搜索,可以通过以下几种方式来扩展功能。 #### 方法一:使用 UTL_MATCH 函数 Oracle 提供了内置函数包 `UTL_MATCH` 来计算字符串之间的编辑距离或相似度。以下是常用的方法: - **EDIT_DISTANCE**:返回两个字符串之间的编辑距离。 - **JARO_WINKLER_SIMILARITY**:返回 Jaro-Winkler 相似度分数(范围为 0 到 100)。 ##### 查询示例 假设有一个名为 `employees` 的表,其中有一列 `name` 存储员工姓名。如果要查找与目标名称 `'John Doe'` 类似的记录,可以执行如下 SQL: ```sql SELECT name, UTL_MATCH.JARO_WINKLER_SIMILARITY(name, 'John Doe') AS similarity_score FROM employees WHERE UTL_MATCH.EDIT_DISTANCE(name, 'John Doe') <= 3 -- 编辑距离不超过3 ORDER BY similarity_score DESC; ``` 上述查询会按照相似度降序排列结果,并过滤掉那些编辑距离超过指定阈值的结果[^1]。 #### 方法二:自定义 PL/SQL 函数集成第三方算法 当默认提供的相似度算法无法完全满足业务需求时,可以选择编写自己的 PL/SQL 函数引入其他高级算法,比如 Levenshtein 距离或其他自然语言处理技术。下面展示一个简单的例子: ##### 创建 Levenshtein Distance 函数 ```plsql CREATE OR REPLACE FUNCTION levenshtein_distance(str1 IN VARCHAR2, str2 IN VARCHAR2) RETURN NUMBER IS len_str1 NUMBER := LENGTH(str1); len_str2 NUMBER := LENGTH(str2); matrix DBMS_SQL.NUMBER_TABLE; BEGIN IF str1 = str2 THEN RETURN 0; END IF; FOR i IN 0..len_str1 LOOP matrix(i * (len_str2 + 1)) := i; END LOOP; FOR j IN 1..len_str2 LOOP matrix(j) := j; END LOOP; FOR i IN 1..len_str1 LOOP FOR j IN 1..len_str2 LOOP IF SUBSTR(str1, i, 1) = SUBSTR(str2, j, 1) THEN cost := 0; ELSE cost := 1; END IF; matrix(i * (len_str2 + 1) + j) := LEAST( matrix((i - 1) * (len_str2 + 1) + j) + 1, matrix(i * (len_str2 + 1) + (j - 1)) + 1, matrix((i - 1) * (len_str2 + 1) + (j - 1)) + cost ); END LOOP; END LOOP; RETURN matrix(len_str1 * (len_str2 + 1) + len_str2); END; / ``` 调用此函数进行模糊匹配: ```sql SELECT name FROM employees WHERE levenshtein_distance(name, 'John Doe') <= 5 ORDER BY name ASC; ``` 这种方法允许开发者灵活调整逻辑以适应特定场景下的复杂需求[^2]。 #### 方法三:利用全文索引结合 Soundex 或 Fuzzy Matching 技术 对于大规模数据集上的高效模糊查询操作,建议启用 Oracle Text 功能创建上下文索引。之后可通过 CONTAINS 子句配合相关选项完成近义词检索任务。 例如设置 SOUNDEX 参数即可开启音码匹配模式: ```sql ALTER INDEX idx_employee_name REBUILD PARAMETERS('SOUNDEX'); ``` 随后运行标准 DML 命令即能获取发音相近的名字列表[^3]。 --- ### 总结 以上介绍了三种主流途径帮助用户实现在 Oracle 环境下开展基于相似性的模糊搜寻工作流。具体选用哪种方案取决于实际应用场景的要求以及性能考量因素。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值