You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Microsoft SQL Server多表Join重复匹配问题求助

解决SQL Server中链接与名称关联的重复匹配问题

你当前的关联逻辑仅通过截取链接右侧与名称长度一致的内容进行匹配,会导致一个链接匹配多个名称的重复问题——比如/http://bla-bla/Test+Link+For+Test替换空格后,既匹配Test Link For Test,又匹配其后缀Link For Test,从而产生重复行。以下两种方法可以解决这个问题:

方法1:保留每个链接的最长匹配项

利用窗口函数ROW_NUMBER(),给每个链接的所有匹配项按名称长度倒序编号,仅保留编号为1的最长匹配结果:

CREATE TABLE #Test1 
(
    link nvarchar(max)
)

CREATE TABLE #Test2
(
    Name nvarchar(max),
)

INSERT INTO #Test1
VALUES
    ('/http://bla-bla/Link+For+Test'),
    ('/http://bla-bla/Test+Link+For+Test'),
    ('/http://bla-bla/Test+Link+For+Test+Second'),
    ('/bla-bla%Link+For+Edited+Test'), 
    ('/bla-bla%2fFor+Test+Edited')

INSERT INTO #Test2
VALUES
    ('Link For Test')
    ,('Test Link For Test')
    ,('Link For Edited Test')
    ,('For Test Edited')

WITH MatchedData AS (
    SELECT
        RIGHT(REPLACE(t1.link, '+', ' '), LEN(t2.[Name])) AS NameFromLink,
        t2.name,
        t1.link,
        ROW_NUMBER() OVER (PARTITION BY t1.link ORDER BY LEN(t2.[Name]) DESC) AS rn
    FROM #Test1 t1
    INNER JOIN #Test2 t2 
        ON RIGHT(REPLACE(t1.link, '+', ' '), LEN(t2.[Name])) = t2.[Name]
)
SELECT NameFromLink, name, link
FROM MatchedData
WHERE rn = 1;

DROP TABLE #Test1
DROP TABLE #Test2

核心逻辑:通过PARTITION BY t1.link按链接分组,ORDER BY LEN(t2.[Name]) DESC让最长的名称排在前面,rn=1筛选出每个链接的最优匹配项。

方法2:优化关联条件,匹配完整末尾段

通过添加额外条件,确保匹配的名称是链接中独立的末尾片段(前面是分隔符/或空格,或链接本身就是该名称),从根源上避免后缀匹配:

CREATE TABLE #Test1 
(
    link nvarchar(max)
)

CREATE TABLE #Test2
(
    Name nvarchar(max),
)

INSERT INTO #Test1
VALUES
    ('/http://bla-bla/Link+For+Test'),
    ('/http://bla-bla/Test+Link+For+Test'),
    ('/http://bla-bla/Test+Link+For+Test+Second'),
    ('/bla-bla%Link+For+Edited+Test'), 
    ('/bla-bla%2fFor+Test+Edited')

INSERT INTO #Test2
VALUES
    ('Link For Test')
    ,('Test Link For Test')
    ,('Link For Edited Test')
    ,('For Test Edited')

SELECT
    RIGHT(REPLACE(t1.link, '+', ' '), LEN(t2.[Name])) AS NameFromLink,
    t2.name,
    t1.link
FROM #Test1 t1
INNER JOIN #Test2 t2 
    ON RIGHT(REPLACE(t1.link, '+', ' '), LEN(t2.[Name])) = t2.[Name]
    AND (
        -- 链接本身长度等于名称长度
        LEN(REPLACE(t1.link, '+', ' ')) = LEN(t2.[Name])
        OR
        -- 匹配部分的前一个字符是分隔符
        SUBSTRING(REPLACE(t1.link, '+', ' '), LEN(REPLACE(t1.link, '+', ' ')) - LEN(t2.[Name]), 1) IN ('/', ' ')
    )

DROP TABLE #Test1
DROP TABLE #Test2

核心逻辑:通过检查匹配片段的前置字符是否为分隔符,确保匹配的是完整的名称段,而非长名称的后缀部分。

内容的提问来源于stack exchange,提问作者Ekaterina Chistyakova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:11:16