如何计算数据表中两个字符串列的相似度百分比?
如何计算数据表中两个字符串列的相似度百分比?
嘿,我懂你的困扰啦!你想用Levenshtein距离计算字符串相似度,结果碰到了'LEVENSHTEIN' is not a recognized built-in function name的报错——这太正常了,因为像SQL Server这类常用数据库,并没有把Levenshtein距离设为内置函数,得咱们自己动手创建一个自定义函数才行。
下面一步步给你讲怎么解决:
第一步:创建自定义的Levenshtein距离函数
你可以先在数据库里运行这段SQL代码,创建一个计算字符串编辑距离的函数:
CREATE FUNCTION dbo.LEVENSHTEIN ( @s NVARCHAR(4000), @t NVARCHAR(4000) ) RETURNS INT AS BEGIN DECLARE @d NVARCHAR(4000), @LD INT, @m INT, @n INT, @i INT, @j INT, @s_i NCHAR(1), @t_j NCHAR(1), @cost INT SET @n = LEN(@s) SET @m = LEN(@t) SET @d = '' IF @n = 0 RETURN @m IF @m = 0 RETURN @n SET @d = CAST(@m AS NVARCHAR(4000)) + ' ' + REPLICATE('0', @m) SET @i = 1 WHILE @i <= @n BEGIN SET @s_i = SUBSTRING(@s, @i, 1) SET @d = CAST(@i AS NVARCHAR(4000)) + ' ' + CAST(@i AS NVARCHAR(4000)) SET @j = 1 WHILE @j <= @m BEGIN SET @t_j = SUBSTRING(@t, @j, 1) SET @cost = CASE WHEN @s_i = @t_j THEN 0 ELSE 1 END SET @d = @d + ' ' + CAST( CASE WHEN SUBSTRING(@d, (@j - 1) * 2 + 1, 2) + 1 < SUBSTRING(@d, @j * 2 + 1, 2) + 1 THEN CASE WHEN SUBSTRING(@d, (@j - 1) * 2 + 1, 2) + 1 < SUBSTRING(@d, (@j - 1) * 2 + 3, 2) + @cost THEN SUBSTRING(@d, (@j - 1) * 2 + 1, 2) + 1 ELSE SUBSTRING(@d, (@j - 1) * 2 + 3, 2) + @cost END ELSE CASE WHEN SUBSTRING(@d, @j * 2 + 1, 2) + 1 < SUBSTRING(@d, (@j - 1) * 2 + 3, 2) + @cost THEN SUBSTRING(@d, @j * 2 + 1, 2) + 1 ELSE SUBSTRING(@d, (@j - 1) * 2 + 3, 2) + @cost END END AS NVARCHAR(4000)) SET @j = @j + 1 END SET @i = @i + 1 END SET @LD = CAST(RIGHT(@d, 2) AS INT) RETURN @LD END GO
第二步:用这个函数计算相似度百分比
相似度的核心公式很直观:
相似度百分比 = (1 - 编辑距离 / 两个字符串的最大长度) × 100
我给你写的查询语句会用ROUND保留两位小数,和你例子里的格式一致,还处理了两个字符串都是空的特殊情况(避免除以0报错)。
假设你的表名叫YourTable,直接运行下面的代码就能得到想要的结果:
SELECT Col_1, Col_2, ROUND( CASE WHEN LEN(Col_1) = 0 AND LEN(Col_2) = 0 THEN 100.0 ELSE (1.0 - dbo.LEVENSHTEIN(Col_1, Col_2) / CAST(CASE WHEN LEN(Col_1) > LEN(Col_2) THEN LEN(Col_1) ELSE LEN(Col_2) END AS FLOAT)) * 100 END, 2 ) AS Col_3 FROM YourTable;
运行后就能得到和你例子里完全匹配的结果:AltonJamesWebs和AltonJamsWebs的相似度是96.55%,BuddarakhGrillIzme和BuddarakhGriIzmezh是89.47%。
额外补充一句:如果你用的是PostgreSQL,可以先启用fuzzystrmatch扩展,直接用内置的levenshtein函数;MySQL则需要安装对应UDF插件才能用内置函数,但SQL Server就得用上面的自定义函数啦。
备注:内容来源于stack exchange,提问作者Isaac A
相关产品推荐
相关产品推荐

