Sql server 预期结果。您需要发布[dbo].[f_ALGORITHM_LEVENSHTEIN]函数,这似乎正在处理两个字符串?从选择dbo.f_GetPercentageOfTwoStringMatching('John Smith Makde','John Smit
Sql server 预期结果。您需要发布[dbo].[f_ALGORITHM_LEVENSHTEIN]函数,这似乎正在处理两个字符串?从选择dbo.f_GetPercentageOfTwoStringMatching('John Smith Makde','John Smit,sql-server,tsql,sql-server-2008-r2,Sql Server,Tsql,Sql Server 2008 R2,预期结果。您需要发布[dbo].[f_ALGORITHM_LEVENSHTEIN]函数,这似乎正在处理两个字符串?从选择dbo.f_GetPercentageOfTwoStringMatching('John Smith Makde','John Smith Makde')得到的预期结果是什么?这里有什么问题吗?如果我理解正确,如果片段相同(比如:John-Smith-Makde==Makde-John-Smith),您希望结果为100%?您可以1)拆分该字符串,按字母顺序排序并比较这些规范化字
预期结果。您需要发布
[dbo].[f_ALGORITHM_LEVENSHTEIN]
函数,这似乎正在处理两个字符串?从选择dbo.f_GetPercentageOfTwoStringMatching('John Smith Makde','John Smith Makde')
得到的预期结果是什么?这里有什么问题吗?如果我理解正确,如果片段相同(比如:John-Smith-Makde==Makde-John-Smith
),您希望结果为100%?您可以1)拆分该字符串,按字母顺序排序并比较这些规范化字符串,或2)拆分该字符串并对每个字符串进行比较,然后计算平均百分比。。。但请先澄清您的需要。@ZoharPeled,我的错,我已经添加了预期结果。我预期给定字符串为100%(1.000),但从第二个方法中,我将获得NULL
输出。如果我删除条件s1.Cs2.C
将获得它,我可以对两个表之间的列执行相同的操作吗?例如,表1的行数很少,表2的行数超过1000万行?我希望给定的字符串为100%(1.000),但从第二种方法中,我得到的是NULL
输出。如果我删除条件s1.Cs2.C
将得到它,我可以对两个表之间的列执行相同的操作吗?例如,表1的行数很少,表2的行数超过1000万行?太好了!大型数据的任何最快匹配百分比(例如table1
有几行
和table2
有超过1000万行
)?@MAK,您必须知道是搜索匹配还是搜索接近度。对于数百万行,必须多久执行一次代价高昂的计算是很重要的。无论何时,只要您可以预计算值(如规范化名称),它都会非常有用。您可以尝试通过排除那些不相似的行来减少行数(通过长度、通过SOUNDEX
等等)。但是百分比的计算必须在运行时进行。对于1000万行,这一定会变慢…我能在给定的规范化方法上获得更多优化吗?因为更新1000万条记录需要5分钟以上。@MAK,首先:请避免后续问题,而是开始一个新问题并在此处放置链接。这将吸引更多的注意力,并在第1期第1个问题中保持干净。同样,您的需求也不完全清楚:我在回答中指出的规范化应该是一次性操作,并且应该保存在附加列或副表中。XML/XQuery
方法不是很快。。。您可以移动到SQL Server 2016并使用STRING\u SPLIT()
或使用CLR函数。但在2008-R2中,你的能力有限。。。我的建议:用更多细节开始一个新问题,并放置一个链接。太好了!大型数据的任何最快匹配百分比(例如table1
有几行
和table2
有超过1000万行
)?@MAK,您必须知道是搜索匹配还是搜索接近度。对于数百万行,必须多久执行一次代价高昂的计算是很重要的。无论何时,只要您可以预计算值(如规范化名称),它都会非常有用。您可以尝试通过排除那些不相似的行来减少行数(通过长度、通过SOUNDEX
等等)。但是百分比的计算必须在运行时进行。对于1000万行,这一定会变慢…我能在给定的规范化方法上获得更多优化吗?因为更新1000万条记录需要5分钟以上。@MAK,首先:请避免后续问题,而是开始一个新问题并在此处放置链接。这将吸引更多的注意力,并在第1期第1个问题中保持干净。同样,您的需求也不完全清楚:我在回答中指出的规范化应该是一次性操作,并且应该保存在附加列或副表中。XML/XQuery
方法不是很快。。。您可以移动到SQL Server 2016并使用STRING\u SPLIT()
或使用CLR函数。但在2008-R2中,你的能力有限。。。我的建议是:用更多细节开始一个新问题,并放置一个链接。
String 1: John Smith Makde
String 2: Makde John Smith
CREATE FUNCTION [dbo].[udf_GetPercentageOfTwoStringMatching]
(
@string1 NVARCHAR(1000)
,@string2 NVARCHAR(1000)
)
RETURNS INT
--WITH ENCRYPTION
AS
BEGIN
DECLARE @levenShteinNumber INT
DECLARE @string1Length INT = LEN(@string1), @string2Length INT = LEN(@string2)
DECLARE @maxLengthNumber INT = CASE WHEN @string1Length > @string2Length THEN @string1Length ELSE @string2Length END
SELECT @levenShteinNumber = [dbo].[f_ALGORITHM_LEVENSHTEIN] (@string1 ,@string2)
DECLARE @percentageOfBadCharacters INT = @levenShteinNumber * 100 / @maxLengthNumber
DECLARE @percentageOfGoodCharacters INT = 100 - @percentageOfBadCharacters
-- Return the result of the function
RETURN @percentageOfGoodCharacters
END
SELECT dbo.f_GetPercentageOfTwoStringMatching('John Smith Makde','Makde John Smith')
7
SELECT dbo.f_GetPercentageOfTwoStringMatching('John Smith Makde','John Smith Makde')
100
100
DECLARE
@String1 VARCHAR(100) = 'John Smith Makde Sr.',
@String2 VARCHAR(100) = 'Makde John Smith Jr.';
SELECT COUNT(*)/(1.*LEN(@String1)-LEN(REPLACE(@string1,' ',''))+1)
FROM
(
SELECT s1.item
FROM dbo.delimitedSplit8K(@String1,' ') AS s1
INTERSECT
SELECT s2.item
FROM dbo.delimitedSplit8K(@String2,' ') AS s2
) AS a
DECLARE
@String1 VARCHAR(100) = 'John Smith Makde Sr.',
@String2 VARCHAR(100) = 'Makde John Smith Jr.';
SELECT (1.*f.L-f.MM)/f.L
FROM
(
SELECT
MM = SUM(ABS(s1.C-s2.C)),
L = CASE WHEN LEN(@String1)>LEN(@string2) THEN LEN(@String1) ELSE LEN(@string2) END
FROM
(
SELECT s1.token, COUNT(*)
FROM samd.NGrams8k(@String1,1) AS s1
GROUP BY s1.token
) AS s1(T,C)
JOIN
(
SELECT s1.token, COUNT(*)
FROM samd.NGrams8k(@String2,1) AS s1
GROUP BY s1.token
) AS s2(T,C)
ON s1.T=s2.T -- Letters that are equal
AND s1.C<>s2.C -- ... but the QTY is different
) AS f;
CREATE TABLE #MockUpYourTable(ID INT IDENTITY, SomeName VARCHAR(1000));
INSERT INTO #MockUpYourTable VALUES('Makde John Smith')
,('Smith John Makde')
,('Some other string')
,('string with with duplicates with');
GO
ALTER TABLE #MockupYourTable ADD NormalizedName VARCHAR(1000);
GO
UPDATE #MockUpYourTable SET NormalizedName=CAST('<x>' + REPLACE((SELECT LOWER(SomeName) AS [*] FOR XML PATH('')),' ','</x><x>') + '</x>' AS XML)
.query(N'
for $fragment in distinct-values(/x/text())
order by $fragment
return $fragment
').value('.','nvarchar(1000)');
GO
SELECT * FROM #MockUpYourTable
ID SomeName NormalizedName
----------------------------------------------------------
1 Makde John Smith john makde smith
2 Smith John Makde john makde smith
3 Some other string other some string
4 string with with duplicates with duplicates string with
--Clean-Up
GO
DROP TABLE #MockUpYourTable