oracle - 以良好的性能在 PL/SQL 中获取相似的字符串
问题描述
我的 Oracle 数据库 (12c) 中有一个大表,我有很多需要相互比较的字符串。我想看看哪些字符串是相似的。
例子:
你好世界波士顿在美国
德国柏林你好世界
应该被检测为类似的字符串,而
你好世界巴黎在法国
你好底特律一个不错的城市
不应被检测为相似。如何在 Oracle PL/SQL 中高效准确地执行此操作?
解决方案
您应该使用在性能和效率之间取得良好平衡的 Dice-Coefficient。它会给你一个数字,代表两个字符串的相似程度。您可以为所有字符串运行此函数,将它们相互比较,然后选择具有大系数的字符串(这些将非常相似)。
-- Dice-Coefficient in Oracle PL/SQL
-- http://en.wikipedia.org/wiki/Dice%27s_coefficient
-- http://en.wikipedia.org/wiki/S%C3%B8rensen_similarity_index
-------------------------------------------------------------------------------
FUNCTION DICE_COEFF(p_str1 IN VARCHAR2, p_str2 IN VARCHAR2) RETURN NUMBER DETERMINISTIC IS
co_substr_len CONSTANT NUMBER := 2;
TYPE ty_varchar_assoc IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100);
v_x ty_varchar_assoc;
v_y ty_varchar_assoc;
v_inter ty_varchar_assoc;
v_part VARCHAR2(10);
BEGIN
-- building set X
FOR i IN 1 .. length(p_str1) - co_substr_len + 1 LOOP
v_part := substr(p_str1, i, co_substr_len);
v_x(v_part) := v_part;
END LOOP;
-- building set Y
FOR i IN 1 .. length(p_str2) - co_substr_len + 1 LOOP
v_part := substr(p_str2, i, co_substr_len);
v_y(v_part) := v_part;
IF v_x.exists(v_part) THEN
v_inter(v_part) := v_part; -- build intersect
END IF;
END LOOP;
RETURN 2 * v_inter.count /(v_x.count + v_y.count);
END DICE_COEFF;
推荐阅读
- wordpress - WordPress:为什么从网络中删除用户会从主/根站点的用户列表中删除所有用户
- logstash - 如果仅指定 certificate_authorities 值,WinLogBeat 使用什么 ssl 证书和密钥?
- python - Pandas:具有备用 y 轴的单系列
- pandas - 如何让空间读取数据框中的整个列?
- karate - 空手道:比较 pdf 响应文件
- windows - VS2015 在另一个线程阻塞时关闭信号量句柄
- reactjs - React + 内部 Flask API:部署的最佳选择是什么?
- terminal - Webstorm的集成终端窗口调整大小时重复多行提示(另一个集成终端可以)
- regex - 正则表达式匹配字符串后跟任何内容或以非数字字符结尾的字符串
- macos - 在特定应用中打开降价链接文件