SQL Server比较一部分地址字符串,2列

时间:2018-06-14 16:15:38

标签: sql-server string tsql comparison

我想请求关于如何对存储在两个单独列中的两个地址值进行部分字符串比较的帮助。即使匹配不是100%,我也只需要识别匹配的值。我不关心街道方向的价值:N,S,E,W,或者它是套房,公寓还是街道类型(rd,st,dr,cr等)。也许仅通过匹配第一个值(门牌号)来满足要求。

一个例子是:

Column1          Column2
17 Wickham CT    17 S WICKHAM CT # 2 << This is a partial match, include
6818 Chester DR  6801 CHESTER DR # A << This is a partial match, include
6301 Raymond RD  6301 RAYMOND RD     << This is a full match, include
6217 Raymond RD  PO BOX 45581        << This doesn't match, don't include

我有查询所有内容的查询,我只需要弄清楚如何过滤我不需要的记录。

如果我能得到任何帮助,那就太棒了。

谢谢。

更新

我认为我对数据的了解要好一些。 我希望我能在以下背景下获得帮助。

OwnerID     Addr_Nbr    Address_A           Address_B
3336223     2204138     11 Westbrook CIR    11 WESTBROOK CIR
3336223     2431628     9 Westbrook CIR     11 WESTBROOK CIR
3337465     2328720     4214 School RD      4214 SCHOOL RD  

在这种情况下,从前两个记录开始,第一个记录似乎是一个匹配,但事实并非如此,因为该所有者有多个地址,第三个记录是一个很好的匹配,因为地址匹配而且只有所有者有一个地址。如何仅选择地址匹配的记录,并且所有者只有一个地址编号?我希望这是有道理的。

再次感谢您

3 个答案:

答案 0 :(得分:1)

尝试使用Levenshtein distance。此链接提供了一些如何使用T-SQL实现它的示例。

Levenshtein距离基本上为您提供了两个字符串之间差异的值。您可以为查询提供可接受的值,并返回达到可接受阈值的任何值。

答案 1 :(得分:0)

您也可以尝试使用Pearson's correlation coefficient

MS SQL is here的完美示例。

这是我的快速组装示例:

--helper function to convert string to ASCII column
CREATE FUNCTION dbo.fn_StringToASCII
(
    @text VARCHAR(MAX)
)
RETURNS @Result TABLE
(
    POS INT,
    NUM INT
)
AS
BEGIN
    DECLARE @i INT
    SET @i = 1
    WHILE @i <= LEN(@text)
    BEGIN
        INSERT INTO @Result
        (
            POS,
            NUM
        )
        VALUES
        (@i, ASCII(SUBSTRING(@text, @i, 1)))
        SET @i = @i + 1
    END
    RETURN;
END;

-- test example
 CREATE TABLE test1(ID INT, ADDR1 VARCHAR(20));
 CREATE TABLE test2(ID INT, ADDR2 VARCHAR(20));

 INSERT INTO dbo.test1
(
    ID,
    ADDR1
)
VALUES
(1, '17 Wickham CT'),
(2, '6818 Chester DR'),
(3, '6217 Raymond RD'),
(4, 'TEST');

INSERT INTO dbo.test2
(
    ID,
    ADDR2
)
VALUES
(1, '17 S WICKHAM CT # 2'),
(2, '6801 CHESTER DR # A'),
(3, 'PO BOX 45581'),
(4, 'TEST');

 --query with coeff
SELECT ISNULL(t1.ID, c2.ID) AS ID,
       (AVG(c1.NUM * c2.NUM) - (AVG(c1.NUM) * AVG(c2.NUM))) / (STDEVP(c1.NUM) * STDEVP(c2.NUM)) AS  Coeff
FROM dbo.test1 t1
    CROSS APPLY dbo.fn_StringToASCII(LOWER(t1.ADDR1)) c1
    RIGHT JOIN
    (
        SELECT t2.ID,
               c2.*
        FROM dbo.test2 t2
            CROSS APPLY dbo.fn_StringToASCII(LOWER(t2.ADDR2)) c2
    ) c2
        ON c2.ID = t1.ID
           AND c2.POS = c1.POS
WHERE 1 = 1
GROUP BY ISNULL(t1.ID, c2.ID);


DROP TABLE dbo.test1
DROP TABLE dbo.test2

/*
results
ID  Coeff
1   0.957280794307261
2   1.58310202187124
3   -0.397204343866094
4   0.987654320987654
*/

答案 2 :(得分:0)

您可以将地址分解为其组件(门牌号,街道名称,街道后缀等),并根据需要单独对其进行比较。

我工作的公司提供了一个工具,用于将地址分解为名为YAddress的组件。它有interfaces for SQL Server,可以直接从T-SQL查询调用。