如何在T-SQL中基于匹配百分比比较可换位的字符串?
T-SQL字符串匹配百分比计算(单词位置无关)
最近碰到一个挺实用的需求:要在T-SQL里对比两个字符串的匹配度,而且字符串里的单词顺序不影响——比如"Joni Bravo"和"Bravo Joni"得算100%匹配。折腾了一番终于搞定,分享给有同样需求的朋友!
核心思路
因为单词顺序不影响,所以核心是把两个字符串拆成唯一单词集合,然后通过「交集单词数 ÷ 并集单词数 × 100」得到匹配百分比。这样不管单词怎么换位,只要单词集合一致,就是100%匹配。
实现步骤
1. 辅助拆分函数(去重)
先写一个辅助函数,用来把字符串按空格拆分,同时过滤掉空字符串和重复单词:
CREATE FUNCTION dbo.SplitAndDeduplicate ( @InputString NVARCHAR(MAX) ) RETURNS TABLE AS RETURN ( SELECT DISTINCT value AS Word FROM STRING_SPLIT(@InputString, ' ') WHERE value <> '' -- 处理连续空格导致的空值 )
2. 主匹配计算函数
然后写主函数,用来计算两个字符串的匹配百分比,同时处理各种边界情况:
CREATE FUNCTION dbo.CalculateStringMatchPercentage ( @String1 NVARCHAR(MAX), @String2 NVARCHAR(MAX) ) RETURNS DECIMAL(5,2) AS BEGIN DECLARE @MatchCount INT, @TotalUniqueWords INT; -- 处理NULL值情况 IF @String1 IS NULL OR @String2 IS NULL RETURN 0.00; -- 优化单单词场景,不用走拆分逻辑 IF CHARINDEX(' ', @String1) = 0 AND CHARINDEX(' ', @String2) = 0 RETURN CASE WHEN @String1 = @String2 THEN 100.00 ELSE 0.00 END; -- 计算两个单词集合的交集数量(匹配的单词数) SELECT @MatchCount = COUNT(*) FROM dbo.SplitAndDeduplicate(@String1) s1 INNER JOIN dbo.SplitAndDeduplicate(@String2) s2 ON s1.Word = s2.Word; -- 计算两个单词集合的并集数量(所有唯一单词数) SELECT @TotalUniqueWords = COUNT(*) FROM ( SELECT Word FROM dbo.SplitAndDeduplicate(@String1) UNION SELECT Word FROM dbo.SplitAndDeduplicate(@String2) ) AS CombinedWords; -- 计算百分比,避免除以0的情况 RETURN CASE WHEN @TotalUniqueWords = 0 THEN 0.00 ELSE CAST(@MatchCount AS DECIMAL(5,2)) / @TotalUniqueWords * 100 END; END
3. 测试示例
来几个测试场景验证效果:
-- 测试1:单词换位,完全匹配 SELECT dbo.CalculateStringMatchPercentage('Joni Bravo', 'Bravo Joni'); -- 返回 100.00 -- 测试2:部分单词匹配 SELECT dbo.CalculateStringMatchPercentage('Joni M Bravo', 'Bravo Joni Smith'); -- 返回 66.67 -- 测试3:单单词匹配 SELECT dbo.CalculateStringMatchPercentage('Alice', 'Alice'); -- 返回 100.00 -- 测试4:单单词不匹配 SELECT dbo.CalculateStringMatchPercentage('Alice', 'Bob'); -- 返回 0.00 -- 测试5:含重复单词的情况 SELECT dbo.CalculateStringMatchPercentage('Joni Joni Bravo', 'Bravo Joni'); -- 返回 100.00
注意事项
- 这个方案默认用空格作为单词分隔符,如果你的字符串用逗号、分号等其他分隔符,只需要修改
STRING_SPLIT里的分隔符参数即可。 - 函数里专门优化了单单词的场景,减少不必要的拆分计算,提升性能。
- 加入了去重逻辑,避免重复单词干扰匹配率(比如重复的"Joni"不会影响最终结果)。
STRING_SPLIT是SQL Server 2016及以上版本才支持的函数,如果是更早的版本,需要自己实现一个字符串拆分函数(比如用递归CTE或者XML解析的方式)。
内容的提问来源于stack exchange,提问作者Georgi Angelov
相关产品推荐
相关产品推荐

