【发布时间】:2020-01-12 06:40:58
【问题描述】:
我正在尝试将 2 列(在 2 个单独的表中)链接在一起,以便如果一列中的每个单词都包含在另一列中,那么它们将匹配。
例如,以下值应匹配:
Paul Smith|Paul Andrew Smith
Paul Smith|Paul Andrew William Smith
Paul William Smith|Paul Andrew William Smith
Paul Andrew Smith|Paul Smith
但不应匹配以下内容:
Paul William Smith|Paul Andrew Smith
我使用的是 SQL Server 2016。
我想通过SELECT 查询来做到这一点。我对使用 string_split 函数(在空格上)有一个模糊的想法,交叉应用 2 个表,然后使用 MAX 函数,但是如果我只处理几千个名称,这将创建数百万行,所以它效率不会很高。
样本数据:
DROP TABLE IF EXISTS #TEMP1
DROP TABLE IF EXISTS #TEMP2
CREATE TABLE #TEMP1 (NAME NVARCHAR(300))
CREATE TABLE #TEMP2 (NAME NVARCHAR(300))
INSERT #TEMP1 SELECT 'Paul Smith'
INSERT #TEMP1 SELECT 'Amy Nicholas Stanton'
INSERT #TEMP1 SELECT 'Andrew James Thomas'
INSERT #TEMP2 SELECT 'Paul Andrew Smith'
INSERT #TEMP2 SELECT 'Amy Stanton'
INSERT #TEMP2 SELECT 'Andrew Marcus Thomas'
所以从样本数据来看,前 2 行应该匹配,3 行不应该匹配。
编辑:我已经将我模糊的想法付诸实践,以下解决方案有效,但正如我所料,当您处理包含数千行的表时,它真的很慢。
SELECT DISTINCT A.[FIRSTNAME],A.[SECONDNAME]
FROM (
SELECT *
,MIN([FIRSTMATCH]) OVER(PARTITION BY [SRN],[FIRSTNAME]) [FM]
,MIN([SECONDMATCH]) OVER(PARTITION BY [FRN],[SECONDNAME]) [SM]
FROM (
SELECT DISTINCT A.NAME [FIRSTNAME]
,B.NAME [SECONDNAME]
,A.value [FIRSTVAL]
,MAX(IIF(A.VALUE=B.VALUE,1,0)) OVER(PARTITION BY A.VALUE,B.RN) [FIRSTMATCH]
,B.value [SECONDVAL]
,MAX(IIF(B.VALUE=A.VALUE,1,0)) OVER(PARTITION BY B.VALUE,A.RN) [SECONDMATCH]
,A.RN [FRN]
,B.RN [SRN]
FROM (
SELECT DISTINCT NAME, DENSE_RANK() OVER(ORDER BY NAME) [RN],value
FROM #TEMP1
CROSS APPLY STRING_SPLIT(LTRIM(RTRIM(NAME)),' ')
WHERE LTRIM(RTRIM(NAME)) !=''
)A
CROSS APPLY(
SELECT DISTINCT NAME, DENSE_RANK() OVER(ORDER BY NAME) [RN],value
FROM #TEMP2
CROSS APPLY STRING_SPLIT(LTRIM(RTRIM(NAME)),' ')
WHERE LTRIM(RTRIM(NAME)) !=''
)B
)A
)A
WHERE A.SM = 1 OR A.FM = 1
【问题讨论】:
-
要求您包含 DDL、示例数据和预期输出,然后逻辑将清晰且易于任何人回答。
-
我的例子算不算样本数据?
-
如果能把当前数据分叉/分离成两张表和预期输出的形式就更好了。
-
我已添加示例数据
标签: sql sql-server fuzzy-logic