【问题标题】:How to find rows in a table with similar string values如何在表中查找具有相似字符串值的行
【发布时间】:2017-12-20 16:45:52
【问题描述】:

我有一个 Microsoft SQL Server 数据库表,其中包含大约 700 万条众包记录,主要包含带有一些相关细节的字符串名称值。对于几乎每条记录,似乎都有十几个类似的拼写错误记录,我正在尝试进行一些模糊匹配来识别记录组,例如“Apple”、“Aple”、“Apples”、“Spple”等。这些名称也可以包含多个单词,它们之间有空格。

我想出了一个使用编辑距离标量函数的解决方案,该函数返回从 string1 转换为 string2 所需的击键次数,并使用该函数将表连接到自身。正如您可以想象的那样,它的性能并不好,因为它必须执行数百万次函数来评估连接。

所以我把它放在一个游标中,因此一次至少只评估一个 string1,这至少会得到结果,但在让它运行几周后,它只评估了 150,000 条记录。有 700 万要评估,我认为我没有我的方法需要的那种时间。

我在字符串名称上放置了全文索引,但是当我没有要搜索的静态值时,我真的找不到使用全文谓词的方法。

有什么想法可以让我以不需要几个月的时间来执行以下操作吗?

 SELECT t1.name, t2.name
 FROM names AS t1
 INNER JOIN names AS t2
      ON EditDistance(t1.name,t2.name) = 1
      AND t1.id != t2.id

【问题讨论】:

  • 这个问题让我想起了soundex函数。
  • 好吧,您的查询的问题在于它几乎就像一个笛卡尔连接。 700 万交叉加入 700 万。并且无法使用索引。哎哟。也许您应该创建一个包含所有已知字典单词的表。并使用该字典仅从您的表中选择未知单词。
  • 是的,笛卡尔连接绝对是问题所在。字典方法似乎很有趣,但另一个问题是名称是多种语言的,并且可以从字面上包含这些语言中的任何单词或单词组合。我不确定我能否获得一个确定的来源用作字典。
  • 好吧,也许您可​​以在表中添加一列,其中包含单词的 4 个字符的 soundex 值。然后在该字段上放置一个索引。然后通过也加入该字段,它至少会最小化加入的记录数量。虽然你可能不会得到每一个模糊匹配,但它应该运行得更快。

标签: sql sql-server full-text-search fuzzy-search data-cleaning


【解决方案1】:

您可以使用DIFFERENCE ( character_expression , character_expression ) 函数来评估每个字符表达式的SOUNDEX 代码的差异。 SOUNDEX 代码用于评估字符串之间的差异。

DIFFERENCE 将返回一个整数 0(可能的最大差异)和 4(可能的最小差异)。您可以利用此值来确定字符串的匹配程度(例如,类似于DIFFERENCE(column1, column2) > 3 的条件将匹配column1column2SOUNDEX 值减1 的记录)。

这里是DIFFERENCE函数的文档链接:https://technet.microsoft.com/en-us/library/ms188753(v=sql.105).aspx

【讨论】:

  • 我使用 SOUNDEX 进行了几次尝试,但没有得到我认为可靠的结果。我需要非常确信这两个字符串应该是相同的,但是我已经看到了几个我无法解释的 SOUNDEX 匹配
【解决方案2】:

您需要找到一种方法来避免将每条记录与其他每条记录进行比较。如果只使用单个字段,可以使用像 trie 这样的特殊数据结构,例如https://github.com/mattandahalfew/Levenshtein_search

【讨论】:

    猜你喜欢
    • 2014-09-04
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多