为什么当切换字符串的顺序进行比较时,Difference函数会给出不同的结果?



在SQL Server中,如果我做以下操作:

Difference ('Kennady', 'Kary') : I get 2

如果我这样做:

Difference ('Kary', 'Kennady') : I get 3.

我认为Difference函数会查看Soundex值,并给出0-4个数字,表示有多少字符是相同的。

SELECT SOUNDEX('Kennady') AS [SoundEx Kennady]
    , SOUNDEX('Kary') AS [SoundEx Kary]
    , DIFFERENCE ('Kennady', 'Kary') AS [Difference Kennady vs Kary]
    , DIFFERENCE ('Kary', 'Kennady') AS [Difference Kary vs Kennady];

这是严格的观察结果。文档非常清楚:

返回的整数是SOUNDEX值中的字符数它们是一样的。返回值范围为0 ~ 4:0表示弱相似或无相似,4表示强相似或相同的值

根据本文档,返回值不应该根据参数的顺序而不同。

从我的查询:"肯尼迪"--> K530和"凯利"--> K600。它们有两个共同的字符,所以值应该是2。

现在,我注意到"Kenn"-> K500。将"Kennady"截断为"Kary"的长度将得到值"3"。嗯。

因此,我认为DIFFERENCE()正在使用第一个参数的长度来截断第二个参数。这使得参数的顺序很重要。

我在其他字符串上尝试了这个。同样的模式似乎有效。我没有找到任何文档说明这种情况。

我想微软会称这是一个"特性"而不是一个"bug";)。

编辑:

以上推测并不完全正确。考虑下面的

  • leepaupauld -> L114
  • leopold -> L143
  • leepaup -> L110
然而,

  • 差值(leepaupauld, leopold) = 4 (!)
  • 差值(leopold, leepaupauld) = 3
  • difference(leepaup, leopold) = 3 (!)
  • 差值(leopold, leepaup) = 2

(!)是我的判断,即给定字符串的soundex值,结果根本没有意义。

所以,问题不在于长度。它是@jpw在注释中指向的底层方法。问题似乎是在一个字符串中有重复的匹配值。但是,根据文档,这些字符不应该多次匹配相同的字符。

我的建议:使用Levenshtein距离。这很有道理。在更长的弦上效果更好。这是理智的。它不是内置的,但是很容易在web上找到任何数据库的实现。

用例子回答。比较"巴希达"one_answers"巴格肖特"

第一名:巴希达Soundex B-343,第二名:Bagshot Soundex- b -230第二搜索第一。第一场:B;下一个搜索从B开始,带3'2'返回不匹配项。第二个匹配是3从第二个匹配第一个3从第一个。迭代从2开始。第三个匹配是第二个匹配第二个匹配第一个匹配3。结果为3.

倒过来-现在第一个是Bagshot Soundex- b -230,第二个是:巴希达Soundex B-343第一场比赛还是B。迭代从2开始。第二个匹配是第一个3从第二个匹配3从第一个。不再进行迭代,因为first中的3是最后一个字母。

说明:来自https://msdn.microsoft.com/en-us/library/ms188753.aspx:"DIFFERENCE和SOUNDEX对排序很敏感。"这意味着每次搜索都从最后一个匹配项开始,并到达序列中的最后一个字符。这就是为什么具有相同字符数和相同字符的两个序列的结果小于4。例如:"Brts"one_answers"Btrs"的差异得出结果2。

参考这里解释算法的最后一篇文章:https://social.msdn.microsoft.com/Forums/en-US/a6ba987d-6fde-40d3-bcd0-4c7fd3d2e8cf/tsql-difference-function-returns-different-results-for-same-query?forum=transactsql

注意:这只是我对正在发生的事情的看法。

根据那篇文章,它使用FIRST参数,然后逐字逐句地查找第二个参数中的匹配项。

举个例子,我的名字"Vogel"= SOUNDEX中的V240。"Vasquez" = V220.

DIFFERENCE('Vogel','Vasquez') = 3

因为它检查"V","2","4"one_answers"0"并找到3个匹配。

然而,

DIFFERENCE('Vasquez','Vogel') = 4

因为它检查"V","2","2"one_answers"0"并找到4个匹配。

如果第一个参数有一个重复数字的soundex,似乎会产生意想不到的结果。

最新更新