在 SQL 中匹配字符串
Matching strings in TSQL
我有一个 table,它有一些包含字符串的列,比方说 nvarchar
。现在,用户将一个字符串传递给一个函数,该函数在其分配的列中搜索该字符串。我想检查该字符串是否存在于数据库中,但问题是它不一定必须是 100% 匹配。
比方说:
用户传递了字符串 Johnathon
并且此数据库中存在字符串 John
。
所以,基本上我想获得 matched.In John
和 Johnathon
这种特殊情况的字符数。它应该是 4 个匹配和 5 个不匹配。
我能得到一些解决这个问题的指导吗?
编辑:我猜我可以在从列中检索到最匹配的字符串后进行百分比匹配。因此,同样地,如果我们忽略匹配和不匹配字符的数量并专注于从数据库中检索匹配的字符串,那应该会起作用。
例如,由于 Johnathon
是由用户传递的,而 John
存在于数据库中,我绝对不能在这里使用 Like
运算符,而是一段搜索代码对于列中最匹配的字符串和 returns 它。
你可以试试这个方法:-
IF EXISTS(SELECT * FROM TAB_NAME WHERE COL LIKE '%JOHN%')
SELECT LEN('JOHN') AS MATCHED, (LEN(COL) - LEN('JOHN')) AS UNMATCHED
FROM TAB_NAME;
我觉得这个方法可以解决你的问题。
@DeadlyJesus 提到的 Levenshtein 距离可能适合您,但另一种方法是从 2 个字符串的开头计算匹配字符。一个简单的用户定义函数可以做到这一点。
create function dbo.MatchStart(@input1 nvarchar(100), @input2 nvarchar(100)) returns int as
begin
declare @i int
set @i = 1
if (@input1 is not null and @input2 is not null)
begin
while (1 = 1)
begin
if (@i > len(@input1) or @i > len(@input2))
break
if (substring(@input1, @i, 1) <> substring(@input2, @i, 1))
break;
set @i = @i + 1
end
end
return @i - 1
end
go
declare @testTable table (text1 nvarchar(100))
declare @userInput nvarchar(100)
insert @testTable values
(null),
(''),
('John'),
('Johnathan'),
('JohXXX'),
('Fred'),
('JxOxHxN')
set @userInput = 'Johnathan'
select text1, dbo.MatchStart(text1, @userInput) as result from @testTable
你可以这样做:
SELECT Name, LEN(Name) AS Equals, (LEN('Johnathon') - LEN(Name)) AS NotEquals
FROM TableName
WHERE 'Johnathon' LIKE '%' +Name +'%'
或者,如果您想比较两种方式,则:
DECLARE @parameter NVARCHAR(MAX) = N'Johnathon'
SELECT Name,
CASE WHEN LEN(Name) > LEN(@parameter) THEN LEN(@parameter) ELSE LEN(Name) END AS Equals,
CASE WHEN LEN(Name) > LEN(@parameter) THEN LEN(Name) - LEN(@parameter) ELSE LEN(@parameter) - LEN(Name) END AS NotEquals
FROM TableName
WHERE Name LIKE '%' + @parameter + '%' OR @parameter LIKE '%' +Name +'%'
我有一个 table,它有一些包含字符串的列,比方说 nvarchar
。现在,用户将一个字符串传递给一个函数,该函数在其分配的列中搜索该字符串。我想检查该字符串是否存在于数据库中,但问题是它不一定必须是 100% 匹配。
比方说:
用户传递了字符串 Johnathon
并且此数据库中存在字符串 John
。
所以,基本上我想获得 matched.In John
和 Johnathon
这种特殊情况的字符数。它应该是 4 个匹配和 5 个不匹配。
我能得到一些解决这个问题的指导吗?
编辑:我猜我可以在从列中检索到最匹配的字符串后进行百分比匹配。因此,同样地,如果我们忽略匹配和不匹配字符的数量并专注于从数据库中检索匹配的字符串,那应该会起作用。
例如,由于 Johnathon
是由用户传递的,而 John
存在于数据库中,我绝对不能在这里使用 Like
运算符,而是一段搜索代码对于列中最匹配的字符串和 returns 它。
你可以试试这个方法:-
IF EXISTS(SELECT * FROM TAB_NAME WHERE COL LIKE '%JOHN%')
SELECT LEN('JOHN') AS MATCHED, (LEN(COL) - LEN('JOHN')) AS UNMATCHED
FROM TAB_NAME;
我觉得这个方法可以解决你的问题。
@DeadlyJesus 提到的 Levenshtein 距离可能适合您,但另一种方法是从 2 个字符串的开头计算匹配字符。一个简单的用户定义函数可以做到这一点。
create function dbo.MatchStart(@input1 nvarchar(100), @input2 nvarchar(100)) returns int as
begin
declare @i int
set @i = 1
if (@input1 is not null and @input2 is not null)
begin
while (1 = 1)
begin
if (@i > len(@input1) or @i > len(@input2))
break
if (substring(@input1, @i, 1) <> substring(@input2, @i, 1))
break;
set @i = @i + 1
end
end
return @i - 1
end
go
declare @testTable table (text1 nvarchar(100))
declare @userInput nvarchar(100)
insert @testTable values
(null),
(''),
('John'),
('Johnathan'),
('JohXXX'),
('Fred'),
('JxOxHxN')
set @userInput = 'Johnathan'
select text1, dbo.MatchStart(text1, @userInput) as result from @testTable
你可以这样做:
SELECT Name, LEN(Name) AS Equals, (LEN('Johnathon') - LEN(Name)) AS NotEquals
FROM TableName
WHERE 'Johnathon' LIKE '%' +Name +'%'
或者,如果您想比较两种方式,则:
DECLARE @parameter NVARCHAR(MAX) = N'Johnathon'
SELECT Name,
CASE WHEN LEN(Name) > LEN(@parameter) THEN LEN(@parameter) ELSE LEN(Name) END AS Equals,
CASE WHEN LEN(Name) > LEN(@parameter) THEN LEN(Name) - LEN(@parameter) ELSE LEN(@parameter) - LEN(Name) END AS NotEquals
FROM TableName
WHERE Name LIKE '%' + @parameter + '%' OR @parameter LIKE '%' +Name +'%'