Я пытаюсь связать 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
(на пробелах), перекрестном применении двух таблиц с использованием функции 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