【问题标题】:Could MySQL query help find similar customer records?MySQL 查询可以帮助找到类似的客户记录吗?
【发布时间】:2012-09-25 06:03:06
【问题描述】:

我有一个提供给我的公司目录,他们希望在 MySQL 数据库中存储和更新。每条公司记录都没有唯一标识符,例如公司 #1234。

这些字段是邮件列表、联系人姓名、公司名称、街道地址、城市、州、邮政编码、电话号码和公司类型的典型字段。更新将再次以 CSV 文件的形式发送给我,没有公司唯一标识符号。

如何将数据库中存储的记录与新记录匹配,以便更新?在这个行业中,联系人姓名可以更改,甚至公司名称也可以更改,因为他们会添加和减去合作伙伴。他们的街道地址可以改变,因为当他们搬家时,他们甚至可以改变他们的电话号码。大多数公司都有一个网站 URL,因此希望它不会经常更改,但也很容易。

我在 MySQL 中看到有类似的匹配 %,这会是匹配记录与新信息的答案吗?

如果有 PHP 解决方案,我在 PHP 中工作。在此先感谢帮助我的好心人!

【问题讨论】:

  • 你为什么不在mysql中添加另一个字段作为你自己的唯一ID。这样您以后就可以识别它们。
  • 感谢您的回复,戴尼斯。我打算这样做,但是如果我不知道要匹配哪个字段来确定它是同一家公司,我该如何将更新的记录与该唯一 ID 匹配?
  • 创建一个差异表,您可以在其中保存 original_id, old_company_name, new_company_name 等日志。

标签: php mysql database match


【解决方案1】:

没有主键,总是很麻烦。

一条线解决方案,确定最适合您要求的规则。

如果我是你,我首先会去客户那里确定一些识别相似记录的规则。这一步是必要的,因为没有主键,因为总是有可能重复输入或更新错误的记录。

规则可以很简单,例如:

1. Available fileds:
    contact name,
    company name,
    street address,
    city,
    state,
    zip code,
    phone number and
    type of company (I Hope this is industry)
2. We will first match company name for similarity like
    select * from table_name where company_name like '%$company_name%'
3. For all found records, match zip code and phone number. If match, break, record needs to be updated
4. If not match found in step 3, match street address. If match, break, record needs to be updated
5. & so on.

您的客户是决定这些规则的最佳人选,因为他是产品的所有者。

另一方面,向客户询问规则对于保证您的安全也很重要,因为在没有主键的情况下,即使经过所有的小心,也总是有可能复制记录和/或更新错误的记录。您可以通过良好的规则尽量减少机会。

【讨论】:

    【解决方案2】:

    正如您所说,表格的所有字段都可以更改,那么我认为没有简单的方法可以在您每次选择任何算法时正确更新表格。
    实现此目的的方法之一可能是要求人员/系统(向您发送更新的记录)也包括 csv 文件中更新字段的旧值。如果您有旧值,您可以轻松地将它们与当前记录匹配并使用新值进行更新。

    【讨论】:

    • 没有主键,没有一种简单的方法可以将现有记录与更新的记录进行匹配。
    • @Edward 这就是我提到的原因 - “还要在 csv 文件中包含更新字段的旧值”。即,如果您获得更新的记录-“A,B,K,D”以及“C已更改为K”的信息,那么您可以轻松地将现有记录“A,B,C,D”更新为“A, B、K、D"。
    【解决方案3】:

    这是一个相当笼统的问题,但解决方案本身在各个项目之间有些独特。

    我将遍历所有按更改时间(或创建日期或更新时间戳等)排序的记录。接下来,我将匹配所有具有相似主要字段的条目:公司名称、地址(尽管这可能有风险)、电话或 url(仅解析域)。然后,我会递归地遍历所有找到的条目,直到找不到更多结果。

    只要它们没有同时更改所有主要列,此算法将有助于找到相同的条目。如果他们这样做了,就无法以编程方式说它是同一家公司。

    这将链接行与看似现在的连接(例如第 1 行和第 3 行)

    例子:

    2001/01/01 Awesome firm, awesome.com
    2002/02/02 Awesome firm, newaddress.com // linked with the first row over company name
    2010/12/05 Ohsome inc, newaddress.com // linked over url
    

    【讨论】:

      【解决方案4】:

      在我早期的 Sql server 项目之一中,我遇到了类似的场景。我曾经做以下事情来处理它。

      1.通常会有2种文件--

      a) 完整提要(每周频率)这将包含供应商数据库中的所有公司 b)增量提要(每日频率)这将仅包含未在完整提要和更新中的新记录。(插入-I,更新-U作为增量提要中的标志)

      2.因此,一旦我收到完整的提要,我将在一周内使用完整提要刷新我的数据库表。此外,我将在此处为每条公司记录提供我的内部 ID。(这些 ID 用于内部目的)

      3.我每天都会根据标记(I-insert,U-update)处理增量提要。

      4.这里有一个非常重要的事情是管理映射表。一旦提要到达,只需为其分配一个新的内部 id。

      5.为了比较数据避免重复,我曾经使用模糊算法得到所有可能的匹配,然后使用通配符过滤和识别哪些是新的和重复的。

      【讨论】:

        【解决方案5】:

        看看Damerau-Levenshtein 距离算法。它计算两个字符串之间的“距离”,并确定将一个字符串转换为另一个字符串需要多少步。步数越少,两个字符串越接近。

        This 文章展示了作为 MySQL 存储函数实现的算法。 Here'sPHP 版本。

        该算法比 LIKE 或 SOUNDEX 好得多。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-05
          • 2011-11-07
          • 2011-07-19
          • 2011-04-28
          • 1970-01-01
          • 1970-01-01
          • 2017-01-08
          • 1970-01-01
          相关资源
          最近更新 更多