【问题标题】:Matching similar city names in SQL在 SQL 中匹配相似的城市名称
【发布时间】:2010-01-08 10:41:54
【问题描述】:

我有一个包含城市名称的表“City”,还有一个我刚刚创建的表,其中包含来自不同来源的城市。当我运行查询以匹配两个表之间的城市时,我发现大约 5000 个不匹配项。

所以请提供一些我可以用来匹配城市的查询(因为有时用户输入的城市名称有一个或两个不同的字符)...我创建了一个运行良好的查询,但我需要这样的查询来匹配更多.

请建议我在这种情况下该怎么做。

SELECT distinct hsm.countryname,co.countryname,hsm.city,co.city
FROM   HotelSourceMap AS hsm
INNER  JOIN 
    (  SELECT c.*,cu.countryName
       FROM   city c
       INNER  JOIN  country cu ON c.countryid= cu.countryId
    ) co
ON (charindex(co.city,hsm.city) > 0 AND hsm.countryid = co.countryid) AND
    hsm.cityid is null

【问题讨论】:

  • 你好,很高兴在这么多天后见到你。

标签: sql sql-server select


【解决方案1】:

如果将Levenshtein Distance算法实现为用户自定义函数,它将返回需要对string_1执行的操作数,使其变为string_2。然后,您可以将 Levenshtein Distance 函数的结果与固定阈值或 string_1 或 string_2 的百分比长度进行比较。

您只需按如下方式使用它:

WHERE LD(city_1, city_2) < 4;

使用Full-Text Search 可能是另一种选择,特别是因为Levenshtein Distance 的实现需要全表扫描。此决定可能取决于您打算进行此比较的频率。

您可能想查看以下 SQL Server 的 Levenshtein Distance 实现:

【讨论】:

  • 我已经按照你所说的创建了函数 Levenshtein,但是当我使用它时它给了我错误找不到列“dbo”或用户定义的函数或聚合“dbo.MIN3”或名称是模棱两可的。我以这种方式使用它(如你所说)从 HotelSourceMap hsm 中选择 hsm.*,城市 c WHERE dbo.LEVENSHTEIN(hsm.city, c.city)
  • 是的,我忘了提。您需要定义 MIN3 函数。使用这个小脚本:tek-tips.com/viewthread.cfm?qid=1194707。将其称为 MIN3 而不是 fnMin3。
  • 现在告诉我需要调用哪个 fnmin3 或 Levenshtein.. 请解释清楚
  • 如果我尝试
  • 完成需要多长时间?
【解决方案2】:

您可以使用Soundex 来比较两个拼写不同但发音相似的字符串。

这取决于它们的拼写方式。如果只是拼写错误,可能使用 Daniel Vassallo 推荐的 Levenshtein Distance。如果是不确定城市拼写方式的人拼写错误,请使用 Soundex。

也许两者都用!

【讨论】:

  • @Mongus:谢谢,对我真的很有帮助。
【解决方案3】:

SoundEx 函数将是此类场景的最佳选择,但仅在单词中的元音不正确或不存在时才有效。如果辅音不匹配,它将不起作用。 另一种方法是编写一个简单的逻辑来定义两个单词之间的适当不匹配限制;虽然不会给出 100% 的准确率,但可能会解决这个目的。一个使用 SoundeEx 函数的简单标量值函数 - 在内部,应该足够了。

【讨论】:

    【解决方案4】:

    最好的解决方案是使用 SOUNDEX。我尝试了一些测试:它匹配 Waterland、Witerland 但不匹配 Wiperland。我认为这应该满足您的要求。 SOUNDEX 将字母字符串转换为四字符代码以查找发音相似的单词或名称。

    select * from HotelSourceMap where SOUNDEX([city]) = SOUNDEX('Waterland')
    

    ==> 匹配

    select * from HotelSourceMap where SOUNDEX([city]) = SOUNDEX('Witerland')
    

    ==> 匹配

    select * from HotelSourceMap where SOUNDEX([city]) = SOUNDEX('Wiperland')
    

    ==> 不匹配

    【讨论】:

    • soundex 适用于单个单词,但不适用于多单词名称,例如 select SOUNDEX('new york'),SOUNDEX('new delhi')
    【解决方案5】:

    我很幸运使用双变音位算法对姓名进行模糊匹配。这个概念类似于 Soundex,因为它将一个词归结为一个代码,但它要复杂得多。在我的数据库中,我将在插入时计算一个“name”字段和一个“nameDoubleMetaphone”字段。这使得搜索和加入非常快。

    维基百科是一个很好的起点:http://en.wikipedia.org/wiki/Double_Metaphone

    【讨论】:

      【解决方案6】:

      您必须修复数据库中的名称。数据库是为了完全匹配,而不是“看起来很像”。最简单的解决方法可能是以 CSV 格式导出表格,将其加载到 Excel 中(两列:主键和城市名称),然后使用拼写检查器来修复名称。修改完所有名称后,再次导入表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-21
        • 1970-01-01
        • 1970-01-01
        • 2014-01-17
        • 2020-05-09
        • 1970-01-01
        • 2020-06-22
        相关资源
        最近更新 更多