【问题标题】:How can I use ~ to fuzzy match two fields of a table?如何使用 ~ 模糊匹配表的两个字段?
【发布时间】:2019-09-03 13:09:11
【问题描述】:

我正在尝试对包含相同公司信息的两个表执行联接,但有时这些公司存储的名称略有不同(例如表 1:公司 X -> 表 2:公司 X 和朋友)。 我的想法是将表 1 的每一行与表 2 的每一行完全连接,然后使用 ~ 进行过滤(例如 where name1 ~ name2 或 name2 ~ name1),但这是不可能的。

有人有解决这个匹配问题的方法吗? 谢谢!

【问题讨论】:

    标签: postgresql join string-matching similarity fuzzy


    【解决方案1】:

    您可以使用“”运算符或pg_trgm提供的'%'运算符进行模糊字符串匹配。

    您必须做出决定,例如您愿意为 '%' 使用什么相似性截止值(如果最佳匹配低于该值,则不返回匹配项)以及是否只想返回顶部匹配项(横向连接对此很有用) 或可能不止一个。

    最好使用它来清理您的数据,而不是直接将其合并到生产应用程序中。

    您可能还需要去掉讨厌的词。 “X 公司和朋友”与“Y 公司和朋友”更相似,而不是“X 公司有限”。

    SELECT t1.*, t2.*, 1- (t1.name <-> t2.name) as similarity
    FROM table1 t1
    INNER JOIN table2 t2
        ON t1.name % t2.name
    order by t1.name <-> t2.name;
    

    【讨论】:

      【解决方案2】:

      您可以加入,条件是任一名称字段是另一个名称字段的子字符串:

      SELECT t1.*, t2.*
      FROM table1 t1
      INNER JOIN table2 t2
          ON t1.name LIKE '%' || t2.name || '%' OR
             t2.name LIKE '%' || t1.name || '%';
      

      这种方法甚至不需要正则表达式。我们可以在这里使用正则表达式,如果我们想确保一个表的名称仅作为另一个名称的子字符串出现 并且 也是一个单词。但是,也许您甚至不需要这样做。

      【讨论】:

        【解决方案3】:

        你可以

        CREATE EXTENSION pg_trgm;
        

        并使用它在连接条件中提供的相似性运算符:

        t1 JOIN t2 ON t1.name % t2.name
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-11
          • 2018-04-30
          • 2021-10-29
          • 2014-12-30
          • 1970-01-01
          相关资源
          最近更新 更多