【问题标题】:How can I compare two tables intelligently?如何智能比较两张表?
【发布时间】:2012-11-18 16:05:33
【问题描述】:

考虑以下是我的两个 sql 表:

表 1                                                                               表 2

+--------+-------------+ +--------+------ ------------------------------------+ |美元 |型号 | |美元 |型号 | +--------+-------------+ +--------+------ ------------------------------------+ | 700 | iPad 2 WiFi 16GB | | 710 | iPad2 WiFi 16GB | | 400 | iPhone 4S 16GB | | 450 | iPhone4S 16GB | | 250 | iPod Touch(第 4 代)8GB | | 200 | iPod Touch 第 4 代 8GB | +--------+-------------+ +--------+------ ------------------------------------+

我一直在智能地比较两个不同表中的数据。我在搜索或比较的上下文中挖掘了很多,我发现了

  • similar_text()
  • soundex()
  • 变音器()
  • LEVENSHTEIN()
  • 喜欢
  • 全文
  • 正则表达式

...在 PHP 和 MySQL 中,但它们都没有效率。因为similar_textLEVENSHTEIN 确实很好,但最糟糕的缺点是它们对于1000 行非常慢,soundex()metaphones 对于这些不相似的项目返回相同的声音,比如“iphone”和“ipad”,两者都不相同等等。我想要做的就是有效地比较两行,就像上面的例子“iPhone 4S 16GB”和“iPhone4S 16GB”一样,我的解决方案应该快速工作以比较这些行。请让我知道我有哪些比较选项,以便我解决我的查询。我真的很感激任何想法,任何提示。

注意:我的一张表包含大约 900 行。

这是以下内容的延续:

Compare two arrays and sort WRT USD

Pattern comparing with mysql between two tables column

【问题讨论】:

  • 我担心这是 AI 完备的,不是吗?
  • 最好的办法是进行一次比较并存储结果。恐怕你不会找到一种莱文斯坦式的算法来提高速度。
  • @H2CO3 好吧,你的恐惧是我亲爱的:-/

标签: php mysql


【解决方案1】:

如果您不喜欢复杂但更有可能产生良好结果的解决方案,那么也许您只想从文本字符串中删除空格并尝试简单的字符串比较.. 或者转换到所有 UPPER 然后比较没有空格。

这至少可以解决您所说的“相似性”示例。

【讨论】:

  • +1 建议 removing spaces 然后使用 like 确实效果很好,但效率很低。我需要像 similar_text or LEVENSHTEIN 这样的东西,因为它们确实为我提供了一些有效的结果,因为我们可以设置比率和百分比水平。我可以有效地利用它吗??
【解决方案2】:

我在做垃圾邮件检测器时涉及到这种事情(大量研究,后来放弃了这个想法,但继续前进......)。

基本上,不要使用like,它在大文本上速度很慢,并且索引有限例如:

LIKE '%hello' 不能使用索引,但是,LIKE 'hello%' 可以。此外,大字段将导致大索引以使工作按您的意图进行(它们适用于通常较短的电子邮件地址)。

使用 = 这也将不区分大小写,您必须这样做。

接下来,向表中添加一个新字段,其中包含已解析的 metaphone() 表示(这意味着只需计算一次)。

现在您有一个包含 1000 条记录的表,每条记录都有其变音位版本以及原始记录。您必须这样做才能获得所需的效率。当您想查看某些文本是否已经存在时,只需将新文本转换为它的 metephone 版本,然后在 db 表中搜索它(在 metephone 解析字段上搜索)。更快;)

为了提高准确性,您可能需要删除所有常用词并删除标点符号,例如:

  • 并且 = 已删除
  • , = 已删除
  • ' = 已删除
  • 已 = 已删除
  • it's = its or it is(取决于您喜欢哪个)

然后将所有多个空格(例如 5 个空格)组合成 1 个空格。

您正在做的事情的性质将有数百个小调整,您可以根据需要对其进行完善。

【讨论】:

  • 好吧,我猜变音位只适用于字符串和`$str = "4gb"; $str2 = "8gb";` 变音位为 KB。在我的情况下,这根本不是有效的,因为 Iphone 8Gb 和 Iphone 4GB 根本不一样。我想我必须在我的报告中提交这个案例的效率是 AI-complete :-/
  • 很容易调整,将数字转换为他们的单词代表,例如“4gb” = “four gb”或“44gb” = “fourfour gb”,只有0,1,2,3, 4,5,6,7,8,9 为之奋斗!这都是“调整”的一部分,所以它对你有用。在这种情况下,只需使用 str_replace(),因为它比正则表达式快得多。
  • 好吧,我做了类似的事情,但没有得到有效的结果。但我想在这种情况下我无法达到 100% 的效率。但是感谢您给我提示以及所有使我产生完全可以接受的结果....
  • 这样的事情你永远不会得到 100%。因此,为什么我删除了基于贝叶斯算法编写的垃圾邮件检测器。此外,您会一直注意到人们编写“单词”的新方式,并且您将永远调整您的代码以适应。
【解决方案3】:

一种方法是创建一个函数/存储过程,该函数/存储过程去除一串空格'(',')',将'Generation'替换为'Gen'等等。之后,您可以创建两个与当前表相同的临时表,但应用“strip_unnecessary()”函数的“模型”字段除外。现在它应该只是加入的问题:将表放在一起或以任何其他方式比较它们。

使用临时表的技巧可以节省一些执行时间,但如果您要经常执行此查询,请考虑使用视图来提高性能。

此解决方案高度依赖于 'strip_unnecessary()' 函数的好坏以及您对“模型”字段内容的了解程度。

【讨论】:

    【解决方案4】:

    从mysql的角度来看,解决方案是这样的:

    SELECT *
    FROM tb1
    WHERE (USD, Model) NOT IN (SELECT USD, Model FROM tb2)
    

    【讨论】:

    • 那根本没有可比性.. 那是不同的 :-/
    • 是的,但如果没有结果,您可以检查是否相同
    猜你喜欢
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2016-09-21
    • 2011-02-10
    相关资源
    最近更新 更多