String Oracle SQL中的高级字符串比较

String Oracle SQL中的高级字符串比较,string,oracle,string-comparison,String,Oracle,String Comparison,我想知道,在Oracle SQL中,是否有一种方法可以比较两个字符串的相似性,而不是像=或那样的相似性。例如,SQL Server有一个函数difference(str1,str2),它比较两个字符串并给出相似性评级(0到4)。不完全是我想要的,但这仍然非常有用 我特别希望函数或方法能够: 逐字符比较字符串(返回精确匹配的数目) 告诉一个字符串中有多少个字符,但位置不对 主要用于长度相同的字符串,其中包含数字(ID、电话号码等)。出于我的目的,我将使用它查找可能的匹配项,其中字母/数字可能已被转

我想知道,在Oracle SQL中,是否有一种方法可以比较两个字符串的相似性,而不是像
=
那样的相似性。例如,SQL Server有一个函数
difference(str1,str2)
,它比较两个字符串并给出相似性评级(0到4)。不完全是我想要的,但这仍然非常有用

我特别希望函数或方法能够:

  • 逐字符比较字符串(返回精确匹配的数目)
  • 告诉一个字符串中有多少个字符,但位置不对
  • 主要用于长度相同的字符串,其中包含数字(ID、电话号码等)。出于我的目的,我将使用它查找可能的匹配项,其中字母/数字可能已被转置
    Soundex(string)
    适用于alpha字符串,但似乎忽略了数字(有充分的理由)

    我没有自己创建函数的特权,但如果有人知道这样做的方法,我会很感兴趣地听到它。比较字符与字符的一种解决方案(只有知道最大字符数时才有效)是:

    但这是你能得到的最不雅的


    任何帮助都将不胜感激。

    听起来您正在寻找

    告诉您将string1转换为string2所需的编辑次数

    SQL> select utl_match.edit_distance( 'Bear', 'berry' ) from dual;
    
    UTL_MATCH.EDIT_DISTANCE('BEAR','BERRY')
    ---------------------------------------
                                          3
    

    还有两个相似性函数
    EDIT\u DISTANCE\u similarity
    JARO\u WINKLER\u similarity
    ,它们给出0到100之间的相似性分数,让您了解字符串的相似性。

    在Oracle中有几种方法可以解决此问题:

  • 您可以创建一个存储过程

  • 您可以将Java代码上载到Oracle数据库,并使用代码()中定义的函数

  • 您可以从数据库中获取字符串并在应用程序中进行比较

  • 优点/缺点:

    存储过程有点难以编写和维护,而且可能速度较慢。但它们是一种标准的、经常使用的工具,因此除非您的公司有严格的“禁止”政策,否则它们通常是“解决方案”(通常类似于正则表达式,解决一个问题并创建两个新问题)

    Java代码是一个非常强大的工具,但我已经看到许多Oracle安装,到目前为止还没有人使用Java代码。我不确定原因是什么,很多人只是看起来很谨慎,但没有什么实质性的东西。还请注意,DB服务器针对IO进行了优化,而针对CPU进行了优化。因此,复杂的Java代码可能会以比您预期的更多的方式破坏您的性能(遵循“许多人都很谨慎”这句话)


    最后一个解决方案总是有效的,但根据您的需要,它可能不是一个选项。另一方面,通过下载大量数据并在应用程序中执行复杂的处理,我看到了性能更好的代码。在一个例子中,查询需要15秒,下载+命令行
    grep(1)
    需要0.3秒。

    这可能是一个可怕的重复。我对这些函数集的可能性感到非常兴奋!这比我希望的要好得多,非常感谢你的帖子。不确定这与Ld()函数是相同还是不同。我相信Ld代表Levenshtein差。@jinglesthula-编辑距离函数确实使用Levenshtein距离算法。我不确定您所指的是哪种语言的
    Ld
    函数--这不是一个作为基本数据库安装一部分的函数--所以我不确定它是否是相同的东西。也许您的组织中有人创建了一个调用
    utl\u匹配的
    LD
    函数?或者他们重新实现了算法。
    SELECT utl_match.edit_distance( string1, string2 )
      FROM dual
    
    SQL> select utl_match.edit_distance( 'Bear', 'berry' ) from dual;
    
    UTL_MATCH.EDIT_DISTANCE('BEAR','BERRY')
    ---------------------------------------
                                          3