JOIN之后的T-SQL标记

时间:2017-11-29 16:12:59

标签: tsql sql-server-2016

我有一个t-sql查询,如下所示:

select * from (
SELECT [Id], replace(ca.[AKey], '-', '') as [AKey1], rtrim(replace(replace(replace(lower([Name]), '#', ''), '(1.0)', ''), '(2.5)', '')) as [Name], [Key], dw.[AKey], replace(lower(trim([wName])), '#', '') as [wName]
  FROM [dbo].[wTable] ca
  FULL JOIN (select * from [dw].[wTable]) dw on 
  rtrim(left( replace(replace(replace(lower(dw.[wName]), '(1.0)', ''), '(2.5)', ''), '#', ''), 5))+'%' 
  like 
  rtrim(left( replace(replace(replace(lower(ca.[Name]    ), '(1.0)', ''), '(2.5)', ''), '#', ''), 5))+'%'

  and 
  right(rtrim(replace(replace(replace(lower(dw.[wName]), '(1.0)', ''), '(2.5)', ''), '#', '')), 2)
  like
  right(rtrim(replace(replace(replace(lower(ca.[Name]    ), '(1.0)', ''), '(2.5)', ''), '#', '')), 2)

  ) tp

正如你所看到的,在JOIN期间,它删除了一些可能存在或可能不存在的模糊字符,并且检查wName列中的前5个字符是否与Name列中的前5个字符匹配,然后对列中的最后2个字符执行相同操作。

基本上,它匹配前5个字符和最后2个字符。

我想要添加的是一个额外的列,它会告诉我结果列是完全匹配还是模糊。换句话说,如果它们是精确匹配,它应该说“真”或类似的东西,如果它们是模糊匹配,我理想地喜欢它告诉我它们有多远。例如,有多少个字符不匹配。

1 个答案:

答案 0 :(得分:1)

正如JNevil所说,你可以使用Levenshtein。您还可以使用Damarau-Levenshtein或最长公共子串,具体取决于您想要获得的准确度以及您的性能期望。

以下是两种解决方案。第一个是使用我从Phil Factor here抓取的副本的Levenshtein解决方案。最长公共子串解决方案使用我的最长公共子串which is fastest available for SQL Server (by far)版本。

-- sample data
declare @t1 table (string1 varchar(100));
declare @t2 table (string2 varchar(100));
insert @t1 values ('abc'),('xxyz'),('1234'),('9923');
insert @t2 values ('abcd'),('xyz'),('2345'),('zzz');

-- Levenshtein    
select string1, string2, Ld 
from
(
  select *, Ld = dbo.LEVENSHTEIN(t1.string1, t2.string2)
  from @t1 t1
  cross join @t2 t2 
) compare 
where ld <= 2;

-- Longest Common Substring    
select string1, string2, lcss = item, lcssLen = itemlen, diff = mx.L-itemLen
from @t1 t1
cross join @t2 t2 
cross apply dbo.lcssWindowAB(t1.string1, t2.string2, 20)
cross apply (values (IIF(len(string1) > len(string2), len(string1),len(string2)))) mx(L)
where mx.L-itemLen <= 2;

<强>结果

string1  string2  Ld   
-------- -------- -----
abc      abcd     1
xxyz     xyz      1
1234     2345     2

string1  string2  lcss  lcssLen     diff
-------- -------- ----- ----------- -----------
abc      abcd     abc   3           1
xxyz     xyz      xyz   3           1
1234     2345     234   3           1
9923     2345     23    2           2

这不能回答你的问题,但应该让你开始。

P.S。我发布的Levenshtein函数确实有一个小错误,它表示&#34; 9923&#34;和&#34; 2345&#34;是4,正确的答案是两个。还有其他Levenshtein功能。