为什么在切换要比较的字符串顺序时,差异函数会给出不同的结果?

时间:2016-10-31 18:05:45

标签: sql-server tsql

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

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

如果我这样做:

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

我认为差异函数会查看引擎盖下的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];

3 个答案:

答案 0 :(得分:4)

这是严格的观察。 documentation非常明确:

  

返回的整数是SOUNDEX值中的字符数   这是一样的。返回值的范围是0到4:0   表示弱相似或不相似,4表示强相似或   相同的价值观。

根据此文档,返回值不应根据参数的顺序而有所不同。

从我的疑问:“Kennady” - > K530和“Kary” - > K600。它们有两个共同的字符,因此值应为2.

现在,我注意到“肯恩” - > K500。将“Kennady”截断为“Kary”的长度会导致值“3”。嗯。

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

我在其他一些字符串上试过这个。相同的模式似乎有效。我没有找到任何指明这种情况的文档。

我想微软会称之为“功能”,而不是“错误”;)。

编辑:

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

  • leepaupauld - > L114
  • leopold - > L143
  • leepaup - > L110

然而,

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

(!)是我的判断,根据字符串的soundex值,结果完全没有意义。

所以,问题不在于长度。这是@jpw在评论中指出的基础方法。问题似乎是一个字符串中的重复匹配值。但是,根据文档,这些文件不应多次匹配相同的字符。

我的建议:使用Levenshtein距离。这说得通。它在更长的字符串上效果更好。这是理智的。它不是内置的,但很容易在网上找到任何数据库的实现。

答案 1 :(得分:0)

以示例回答。 比较'Bathilda'和'Bagshott'

第一名:Bathilda Soundex B-343,第二名:Bagshot Soundex-B-230 第二次搜索。 第一场比赛:B;下一次搜索在B之后开始,为3 '2'不匹配。 第二场比赛是第二场比赛,第一场比赛是第3场比赛。 迭代从2开始。 第三场比赛是第二场比赛的第3场,第二场比赛是第3场 结果是3。

反向 - 现在第一个是Bagshot Soundex-B-230,第二个是:Bathilda Soundex B-343 第一场比赛又是B. 迭代从2开始。 第二场比赛是第一场比赛的第3场比赛。 不再进行迭代,因为第一个是最后一个字母。

说明:FROM https://msdn.microsoft.com/en-us/library/ms188753.aspx: “DIFFERENCE和SOUNDEX是整理敏感的。” 这意味着每次搜索都会在最后一次匹配后开始,然后转到序列中的最后一个char。 这就是为什么两个具有相同字符数和相同字符的序列给出的结果小于4。 例如:“Brts”和“Btrs”的差异给出结果2。

答案 2 :(得分:0)

参考此处的最后一篇文章解释算法: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"和" 0"并找到3场比赛。

然而,

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

因为它会检查" V"," 2"," 2"和" 0"并找到4场比赛。

似乎第一个参数的soundex具有任何重复数字,它可能会产生意外结果。