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

use*_*554 9 t-sql sql-server

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

Difference ('Kennady', 'Kary') : I get 2
Run Code Online (Sandbox Code Playgroud)

如果我做:

Difference ('Kary', 'Kennady') : I get 3.
Run Code Online (Sandbox Code Playgroud)

我认为差异函数会查看引擎盖下的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];
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 5

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

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

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

根据我的查询:“Kennady”--> K530 和“Kary”--> K600。它们有两个共同字符,因此该值应为 2。

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

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

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

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

编辑:

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

  • 利波波 --> L114
  • 利奥波德 --> L143
  • 利波普 --> L110

然而,

  • 差异(leepaupauld,利奥波德)= 4(!)
  • 差异(利奥波德,利波波德)= 3
  • 差异(leepaup,leopold)= 3(!)
  • 差异(利奥波德,利帕普)= 2

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

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

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