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

Oracle中对比格式不同的两列地址数据(缩写与全称差异)

Oracle地址匹配(缩写/全称差异处理)

针对两张表中地址因缩写(如SE、Ave、St)和全称(如Southeast、Avenue、Street)导致的匹配问题,可通过以下两种方案实现准确对比:

方案1:自定义地址标准化函数

创建PL/SQL函数将地址统一转换为标准格式(例如全部转为全称),之后直接对比转换结果即可。

示例函数

CREATE OR REPLACE FUNCTION normalize_address(p_address IN VARCHAR2) RETURN VARCHAR2 IS
    v_result VARCHAR2(1000);
BEGIN
    -- 统一转大写,消除大小写差异
    v_result := UPPER(p_address);
    
    -- 按从长到短顺序替换缩写为全称,避免部分匹配错误
    v_result := REGEXP_REPLACE(v_result, '\bSE\b', 'SOUTHEAST');
    v_result := REGEXP_REPLACE(v_result, '\bSW\b', 'SOUTHWEST');
    v_result := REGEXP_REPLACE(v_result, '\bNE\b', 'NORTHEAST');
    v_result := REGEXP_REPLACE(v_result, '\bNW\b', 'NORTHWEST');
    v_result := REGEXP_REPLACE(v_result, '\bE\b', 'EAST');
    v_result := REGEXP_REPLACE(v_result, '\bW\b', 'WEST');
    v_result := REGEXP_REPLACE(v_result, '\bN\b', 'NORTH');
    v_result := REGEXP_REPLACE(v_result, '\bS\b', 'SOUTH');
    v_result := REGEXP_REPLACE(v_result, '\bAVE\b', 'AVENUE');
    v_result := REGEXP_REPLACE(v_result, '\bST\b', 'STREET');
    v_result := REGEXP_REPLACE(v_result, '\bRD\b', 'ROAD');
    v_result := REGEXP_REPLACE(v_result, '\bBLVD\b', 'BOULEVARD');
    
    -- 清洗多余空格:多空格转单空格,去除首尾空格
    v_result := REGEXP_REPLACE(v_result, '\s+', ' ');
    v_result := TRIM(v_result);
    
    RETURN v_result;
END;
/

使用方式

SELECT 
    a.address AS addr1,
    b.address AS addr2,
    CASE WHEN normalize_address(a.address) = normalize_address(b.address) THEN 'true' ELSE 'false' END AS is_match
FROM table_a a
JOIN table_b b ON normalize_address(a.address) = normalize_address(b.address);

方案2:查询中直接嵌套正则替换(无需创建函数)

如果只是临时查询,可直接在SQL中嵌入替换逻辑,无需创建函数:

SELECT 
    a.address AS addr1,
    b.address AS addr2,
    CASE 
        WHEN TRIM(REGEXP_REPLACE(REGEXP_REPLACE(UPPER(a.address), 
            '\b(SE|SW|NE|NW|E|W|N|S|AVE|ST|RD|BLVD)\b', 
            CASE 
                WHEN '\1' = 'SE' THEN 'SOUTHEAST'
                WHEN '\1' = 'SW' THEN 'SOUTHWEST'
                WHEN '\1' = 'NE' THEN 'NORTHEAST'
                WHEN '\1' = 'NW' THEN 'NORTHWEST'
                WHEN '\1' = 'E' THEN 'EAST'
                WHEN '\1' = 'W' THEN 'WEST'
                WHEN '\1' = 'N' THEN 'NORTH'
                WHEN '\1' = 'S' THEN 'SOUTH'
                WHEN '\1' = 'AVE' THEN 'AVENUE'
                WHEN '\1' = 'ST' THEN 'STREET'
                WHEN '\1' = 'RD' THEN 'ROAD'
                WHEN '\1' = 'BLVD' THEN 'BOULEVARD'
            END), '\s+', ' '))
        = TRIM(REGEXP_REPLACE(REGEXP_REPLACE(UPPER(b.address), 
            '\b(SE|SW|NE|NW|E|W|N|S|AVE|ST|RD|BLVD)\b', 
            CASE 
                WHEN '\1' = 'SE' THEN 'SOUTHEAST'
                WHEN '\1' = 'SW' THEN 'SOUTHWEST'
                WHEN '\1' = 'NE' THEN 'NORTHEAST'
                WHEN '\1' = 'NW' THEN 'NORTHWEST'
                WHEN '\1' = 'E' THEN 'EAST'
                WHEN '\1' = 'W' THEN 'WEST'
                WHEN '\1' = 'N' THEN 'NORTH'
                WHEN '\1' = 'S' THEN 'SOUTH'
                WHEN '\1' = 'AVE' THEN 'AVENUE'
                WHEN '\1' = 'ST' THEN 'STREET'
                WHEN '\1' = 'RD' THEN 'ROAD'
                WHEN '\1' = 'BLVD' THEN 'BOULEVARD'
            END), '\s+', ' '))
        THEN 'true' 
        ELSE 'false' 
    END AS is_match
FROM table_a a, table_b b
WHERE TRIM(REGEXP_REPLACE(REGEXP_REPLACE(UPPER(a.address), 
            '\b(SE|SW|NE|NW|E|W|N|S|AVE|ST|RD|BLVD)\b', 
            CASE 
                WHEN '\1' = 'SE' THEN 'SOUTHEAST'
                WHEN '\1' = 'SW' THEN 'SOUTHWEST'
                WHEN '\1' = 'NE' THEN 'NORTHEAST'
                WHEN '\1' = 'NW' THEN 'NORTHWEST'
                WHEN '\1' = 'E' THEN 'EAST'
                WHEN '\1' = 'W' THEN 'WEST'
                WHEN '\1' = 'N' THEN 'NORTH'
                WHEN '\1' = 'S' THEN 'SOUTH'
                WHEN '\1' = 'AVE' THEN 'AVENUE'
                WHEN '\1' = 'ST' THEN 'STREET'
                WHEN '\1' = 'RD' THEN 'ROAD'
                WHEN '\1' = 'BLVD' THEN 'BOULEVARD'
            END), '\s+', ' '))
        = TRIM(REGEXP_REPLACE(REGEXP_REPLACE(UPPER(b.address), 
            '\b(SE|SW|NE|NW|E|W|N|S|AVE|ST|RD|BLVD)\b', 
            CASE 
                WHEN '\1' = 'SE' THEN 'SOUTHEAST'
                WHEN '\1' = 'SW' THEN 'SOUTHWEST'
                WHEN '\1' = 'NE' THEN 'NORTHEAST'
                WHEN '\1' = 'NW' THEN 'NORTHWEST'
                WHEN '\1' = 'E' THEN 'EAST'
                WHEN '\1' = 'W' THEN 'WEST'
                WHEN '\1' = 'N' THEN 'NORTH'
                WHEN '\1' = 'S' THEN 'SOUTH'
                WHEN '\1' = 'AVE' THEN 'AVENUE'
                WHEN '\1' = 'ST' THEN 'STREET'
                WHEN '\1' = 'RD' THEN 'ROAD'
                WHEN '\1' = 'BLVD' THEN 'BOULEVARD'
            END), '\s+', ' '));

注意事项

  • 正则中的\b是单词边界,可避免替换到单词中间的字符(比如防止把"STONE"中的"ST"替换成"STREET")
  • 替换顺序需优先处理长缩写(如先替换SE/SW,再替换S/E),防止短缩写先匹配导致长缩写被错误拆分
  • 可根据业务需求扩展更多缩写/全称对应关系,比如添加LN对应LANE、DR对应DRIVE等
  • 若地址存在其他格式差异(如数字与街道名顺序颠倒、额外标点),需补充对应的清洗逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:41:12