如何从 Oracle 表中获取几乎匹配的字符串?
Posted
技术标签:
【中文标题】如何从 Oracle 表中获取几乎匹配的字符串?【英文标题】:How to get almost matching string from Oracle table? 【发布时间】:2015-07-08 05:23:15 【问题描述】:我在 Oracle 中有一个包含四列的表。
现在用户可以在我的查询中输入输入字符串“右膝操作”(这是有效的),我的查询应该返回与 DiagnosisName 列中大部分单词匹配的 ICD 代码 (IKR123)。
以下是我当前的查询。(没有给出正确的输出)
SELECT diagnosisname
FROM
(SELECT diagnosisname,
UTL_MATCH.jaro_winkler_similarity('%operation Knee right%',diagnosisname)
FROM icd_code
ORDER BY UTL_MATCH.EDIT_DISTANCE_SIMILARITY('%operation Knee right%',diagnosisname) DESC
)
WHERE ROWNUM<2;
这个查询给我的输出是“左膝手术”,但我的期望是“右膝手术”。
【问题讨论】:
【参考方案1】:请试试这个查询。这可能有助于解决您的问题。
SELECT diagnosisname
FROM (SELECT diagnosisname, UTL_MATCH.jaro_winkler_similarity('%operation Knee right%',diagnosisname)
FROM icd_code
WHERE UTL_MATCH.jaro_winkler_similarity('%operation Knee right%',diagnosisname) = 100
ORDER BY UTL_MATCH.EDIT_DISTANCE_SIMILARITY('%operation Knee right%',diagnosisname) DESC)
WHERE ROWNUM<2
【讨论】:
你好@Pankaj,你正在比较 UTL_MATCH.jaro_winkler_similarity('%operation Knee right%',diagnosisname) = 100 这意味着第一个字符串和第二个字符串都应该完全匹配。但是我的要求是,即使它部分(但几乎)匹配也应该有效。但是您的查询什么也没返回。【参考方案2】:关于UTL_MATCH的使用有几点需要注意:
EDIT_DISTANCE_SIMILARITY:返回 0 到 100 之间的整数,其中 0 表示完全不相似,100 表示完全匹配。 JARO_WINKLER_SIMILARITY:返回 0 到 100 之间的整数,其中 0 表示完全不相似,100 表示完全匹配,但会尝试考虑可能的数据输入错误。ORDER BY UTL_MATCH.EDIT_DISTANCE_SIMILARITY('%operation Knee right%',diagnosisname) DESC
这不会给你正确的结果。因为,您只考虑可能的相似性,而没有考虑数据输入错误。因此,您必须使用 JARO_WINKLER_SIMILARITY。
右膝手术
您需要记住输入的 CASE 和要比较的列值。它们必须在相似的情况下才能正确匹配。您在 LOWERCASE 中传递输入,但是,您的列值在 INITCAP 中。更好地将列值和输入转换为类似的情况。
我们看下面的演示来了解一下:
SQL> WITH DATA AS(
2 SELECT 'Heart Operation' diagnosis_name, 'IH123' icd_code FROM dual UNION ALL
3 SELECT 'Knee Operation' diagnosis_name, 'IK123' icd_code FROM dual UNION ALL
4 SELECT 'Left Knee Operation' diagnosis_name, 'IKL123' icd_code FROM dual UNION ALL
5 SELECT 'Right Knee Operation' diagnosis_name, 'IKR123' icd_code FROM dual UNION ALL
6 SELECT 'Fever' diagnosis_name, 'IF123' icd_code FROM dual
7 )
8 SELECT t.*,
9 utl_match.edit_distance_similarity(upper(diagnosis_name),upper('operation Knee right')) eds,
10 UTL_MATCH.jaro_winkler_similarity (upper(diagnosis_name),upper('operation Knee right')) jws
11 FROM DATA t
12 ORDER BY jws DESC
13 /
DIAGNOSIS_NAME ICD_CO EDS JWS
-------------------- ------ ---------- ----------
Right Knee Operation IKR123 20 72
Knee Operation IK123 20 70
Heart Operation IH123 25 68
Left Knee Operation IKL123 25 64
Fever IF123 15 47
SQL>
因此,您会看到两者之间的不同之处。 jaro_winkler_similarity 在识别数据输入错误和提供最接近的匹配方面做得更好。在此基础上,只需将第一行按降序排序即可:
SQL> WITH DATA AS(
2 SELECT 'Heart Operation' diagnosis_name, 'IH123' icd_code FROM dual UNION ALL
3 SELECT 'Knee Operation' diagnosis_name, 'IK123' icd_code FROM dual UNION ALL
4 SELECT 'Left Knee Operation' diagnosis_name, 'IKL123' icd_code FROM dual UNION ALL
5 SELECT 'Right Knee Operation' diagnosis_name, 'IKR123' icd_code FROM dual UNION ALL
6 SELECT 'Fever' diagnosis_name, 'IF123' icd_code FROM dual
7 )
8 SELECT diagnosis_name
9 FROM
10 (SELECT t.*,
11 utl_match.edit_distance_similarity(upper(diagnosis_name),upper('operation Knee right')) eds,
12 UTL_MATCH.jaro_winkler_similarity (upper(diagnosis_name),upper('operation Knee right')) jws
13 FROM DATA t
14 ORDER BY jws DESC
15 )
16 WHERE rownum = 1
17 /
DIAGNOSIS_NAME
--------------------
Right Knee Operation
SQL>
【讨论】:
嗨@Lalit,您的查询工作正常,但用户也可以输入 operation crime rt 而不是 operation crime right。左=lt,右=lt等, @shary.sharath 您可以使用DECODE
自定义一些东西。该功能为您提供最接近的匹配,但很少有超出该功能范围的内容。您需要显式编写查询来处理可能存在歧义的情况。例如,operation knee rt
将给出两行,因为两者都是紧密匹配的。但是,如果您将rt
解码为right
并将lt
解码为left
,您将获得所需的输出。请将其标记为已回答。
您好@Lalit,我使用了您的查询SELECT diagnosisname FROM ( SELECT diagnosisname,utl_match.edit_distance_similarity(UPPER(diagnosisname),UPPER('knee operation Left ')) eds, UTL_MATCH.jaro_winkler_similarity (UPPER(diagnosisname),UPPER('knee operation Left ')) jws FROM icd_code ORDER BY jws DESC ) WHERE ROWNUM = 1
,但它返回的是膝盖操作而不是左膝盖操作。我现在该怎么办?
嗯,那是因为Knee Operation
与前两个词完美匹配。让我给你一个解决方法,同时你可以试试这个lalitkumarb.wordpress.com/2014/12/02/…你可以将字符串拆分为单个单词并使用IN
运算符进行比较。
对于句子中的单词匹配 jaro 或编辑哪个会更好?以上是关于如何从 Oracle 表中获取几乎匹配的字符串?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle regexp_replace 挑选出模式匹配组