TSQL 查询以匹配不同长度的字符串

Gee*_*zer 4 sql-server azure-sql-database query-performance

我正在编写一个 TVF 来查询一个大表(数千万行),其中该表中的字符串(邮政编码)与另一个表中的字符串(部分邮政编码(输出代码/扇区部分))匹配。

我遇到了无法解决的边缘情况。

对于那些不熟悉英国邮政编码的人 在此输入图像描述

这是一些示例数据。

DECLARE @tab1 TABLE (Sk INT, Postcode VARCHAR(8))
DECLARE @tab2 TABLE (Sk INT, Coverage VARCHAR(8)) 

INSERT INTO @tab1 (Sk, Postcode) VALUES (1, 'E12 5HH'), (6, 'SW1X 6AA')
INSERT INTO @tab2 (Sk, Coverage) VALUES (1, 'E12'), (1, 'E12 5'), 
                                        (2, 'E1'), (2, 'E11'), (2, 'E13'), 
                                        (3, 'E12 6'),
                                        (4, 'E12 5') ,
                                        (5, 'E12') ,
                                        (7, 'SW1') ,
                                        (8, 'SW1X') 
Run Code Online (Sandbox Code Playgroud)

和我当前的查询

SELECT  S.Sk, 
        S.Postcode, 
        CoverageSk = X.Sk, 
        X.Coverage 
FROM        @tab1   S 
OUTER APPLY (
    SELECT  Sk , 
            Coverage , 
            [Length] = LEN(Coverage) 
    FROM    @tab2
)   X 
WHERE   S.Sk <> X.Sk 
AND     LEFT(S.Postcode,X.[Length] ) = X.Coverage 
Run Code Online (Sandbox Code Playgroud)

这些是我的结果。

在此输入图像描述

第 1 行和第 4 行的数据不应出现在结果中。第 1 行,覆盖范围或输出代码“E1”与邮政编码“E12 5HH”的输出代码部分(“E12”)不同。

第 4 行也是如此,覆盖范围或输出代码“SW1”与邮政编码“SW1X 6AA”的输出代码(“SW1X”)部分不同。

Pau*_*ite 5

理想情况下,源表将分解各个组成部分,以便您可以直接匹配它们。

如果不可能,这适用于示例数据:

SELECT 
    T1.Sk, 
    T1.Postcode, 
    CoverageSk = T2.Sk, 
    T2.Coverage 
FROM @tab1 AS T1
JOIN @tab2 AS T2
    ON T2.Sk <> T1.Sk
    AND T1.Postcode LIKE 
            CASE
                WHEN CHARINDEX(SPACE(1), T2.Coverage) > 0 
                THEN T2.Coverage
                ELSE T2.Coverage + SPACE(1)
            END + '%';
Run Code Online (Sandbox Code Playgroud)
斯克 邮政编码 覆盖范围 覆盖范围
1 E12 5HH 4 E12 5
1 E12 5HH 5 E12
6 SW1X 6AA 8 SW1X

SQL Server 可以通过动态查找使用邮政编码上的索引:

动态寻道